Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.26
This commit is contained in:
@@ -241,10 +241,25 @@ config NF_NAT_SNMP_BASIC
|
||||
# <expr> '&&' <expr> (6)
|
||||
#
|
||||
# (6) Returns the result of min(/expr/, /expr/).
|
||||
config NF_NAT_PROTO_DCCP
|
||||
tristate
|
||||
depends on NF_NAT && NF_CT_PROTO_DCCP
|
||||
default NF_NAT && NF_CT_PROTO_DCCP
|
||||
|
||||
config NF_NAT_PROTO_GRE
|
||||
tristate
|
||||
depends on NF_NAT && NF_CT_PROTO_GRE
|
||||
|
||||
config NF_NAT_PROTO_UDPLITE
|
||||
tristate
|
||||
depends on NF_NAT && NF_CT_PROTO_UDPLITE
|
||||
default NF_NAT && NF_CT_PROTO_UDPLITE
|
||||
|
||||
config NF_NAT_PROTO_SCTP
|
||||
tristate
|
||||
default NF_NAT && NF_CT_PROTO_SCTP
|
||||
depends on NF_NAT && NF_CT_PROTO_SCTP
|
||||
|
||||
config NF_NAT_FTP
|
||||
tristate
|
||||
depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
|
||||
|
@@ -10,7 +10,7 @@ nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
|
||||
endif
|
||||
endif
|
||||
|
||||
nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
|
||||
nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_common.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
|
||||
iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o
|
||||
|
||||
# connection tracking
|
||||
@@ -29,7 +29,10 @@ obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
|
||||
obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
|
||||
|
||||
# NAT protocols (nf_nat)
|
||||
obj-$(CONFIG_NF_NAT_PROTO_DCCP) += nf_nat_proto_dccp.o
|
||||
obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
|
||||
obj-$(CONFIG_NF_NAT_PROTO_UDPLITE) += nf_nat_proto_udplite.o
|
||||
obj-$(CONFIG_NF_NAT_PROTO_SCTP) += nf_nat_proto_sctp.o
|
||||
|
||||
# generic IP tables
|
||||
obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
|
||||
|
@@ -59,7 +59,7 @@ do { \
|
||||
#endif
|
||||
|
||||
static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
|
||||
char *hdr_addr, int len)
|
||||
const char *hdr_addr, int len)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
@@ -80,8 +80,8 @@ static inline int arp_packet_match(const struct arphdr *arphdr,
|
||||
const char *outdev,
|
||||
const struct arpt_arp *arpinfo)
|
||||
{
|
||||
char *arpptr = (char *)(arphdr + 1);
|
||||
char *src_devaddr, *tgt_devaddr;
|
||||
const char *arpptr = (char *)(arphdr + 1);
|
||||
const char *src_devaddr, *tgt_devaddr;
|
||||
__be32 src_ipaddr, tgt_ipaddr;
|
||||
int i, ret;
|
||||
|
||||
@@ -222,16 +222,16 @@ unsigned int arpt_do_table(struct sk_buff *skb,
|
||||
unsigned int hook,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
struct arpt_table *table)
|
||||
struct xt_table *table)
|
||||
{
|
||||
static const char nulldevname[IFNAMSIZ];
|
||||
unsigned int verdict = NF_DROP;
|
||||
struct arphdr *arp;
|
||||
const struct arphdr *arp;
|
||||
bool hotdrop = false;
|
||||
struct arpt_entry *e, *back;
|
||||
const char *indev, *outdev;
|
||||
void *table_base;
|
||||
struct xt_table_info *private;
|
||||
const struct xt_table_info *private;
|
||||
|
||||
if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
|
||||
return NF_DROP;
|
||||
@@ -352,7 +352,7 @@ static int mark_source_chains(struct xt_table_info *newinfo,
|
||||
e->counters.pcnt = pos;
|
||||
|
||||
for (;;) {
|
||||
struct arpt_standard_target *t
|
||||
const struct arpt_standard_target *t
|
||||
= (void *)arpt_get_target(e);
|
||||
int visited = e->comefrom & (1 << hook);
|
||||
|
||||
@@ -437,7 +437,7 @@ static int mark_source_chains(struct xt_table_info *newinfo,
|
||||
|
||||
static inline int check_entry(struct arpt_entry *e, const char *name)
|
||||
{
|
||||
struct arpt_entry_target *t;
|
||||
const struct arpt_entry_target *t;
|
||||
|
||||
if (!arp_checkentry(&e->arp)) {
|
||||
duprintf("arp_tables: arp check failed %p %s.\n", e, name);
|
||||
@@ -457,7 +457,7 @@ static inline int check_entry(struct arpt_entry *e, const char *name)
|
||||
static inline int check_target(struct arpt_entry *e, const char *name)
|
||||
{
|
||||
struct arpt_entry_target *t;
|
||||
struct arpt_target *target;
|
||||
struct xt_target *target;
|
||||
int ret;
|
||||
|
||||
t = arpt_get_target(e);
|
||||
@@ -480,7 +480,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
|
||||
unsigned int *i)
|
||||
{
|
||||
struct arpt_entry_target *t;
|
||||
struct arpt_target *target;
|
||||
struct xt_target *target;
|
||||
int ret;
|
||||
|
||||
ret = check_entry(e, name);
|
||||
@@ -706,11 +706,11 @@ static void get_counters(const struct xt_table_info *t,
|
||||
}
|
||||
}
|
||||
|
||||
static inline struct xt_counters *alloc_counters(struct arpt_table *table)
|
||||
static inline struct xt_counters *alloc_counters(struct xt_table *table)
|
||||
{
|
||||
unsigned int countersize;
|
||||
struct xt_counters *counters;
|
||||
struct xt_table_info *private = table->private;
|
||||
const struct xt_table_info *private = table->private;
|
||||
|
||||
/* We need atomic snapshot of counters: rest doesn't change
|
||||
* (other than comefrom, which userspace doesn't care
|
||||
@@ -731,7 +731,7 @@ static inline struct xt_counters *alloc_counters(struct arpt_table *table)
|
||||
}
|
||||
|
||||
static int copy_entries_to_user(unsigned int total_size,
|
||||
struct arpt_table *table,
|
||||
struct xt_table *table,
|
||||
void __user *userptr)
|
||||
{
|
||||
unsigned int off, num;
|
||||
@@ -851,7 +851,7 @@ static int compat_table_info(const struct xt_table_info *info,
|
||||
static int get_info(struct net *net, void __user *user, int *len, int compat)
|
||||
{
|
||||
char name[ARPT_TABLE_MAXNAMELEN];
|
||||
struct arpt_table *t;
|
||||
struct xt_table *t;
|
||||
int ret;
|
||||
|
||||
if (*len != sizeof(struct arpt_getinfo)) {
|
||||
@@ -872,7 +872,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
||||
"arptable_%s", name);
|
||||
if (t && !IS_ERR(t)) {
|
||||
struct arpt_getinfo info;
|
||||
struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = t->private;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (compat) {
|
||||
@@ -911,7 +911,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
|
||||
{
|
||||
int ret;
|
||||
struct arpt_get_entries get;
|
||||
struct arpt_table *t;
|
||||
struct xt_table *t;
|
||||
|
||||
if (*len < sizeof(get)) {
|
||||
duprintf("get_entries: %u < %Zu\n", *len, sizeof(get));
|
||||
@@ -927,7 +927,8 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
|
||||
|
||||
t = xt_find_table_lock(net, NF_ARP, get.name);
|
||||
if (t && !IS_ERR(t)) {
|
||||
struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = t->private;
|
||||
|
||||
duprintf("t->private->number = %u\n",
|
||||
private->number);
|
||||
if (get.size == private->size)
|
||||
@@ -936,7 +937,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
|
||||
else {
|
||||
duprintf("get_entries: I've got %u not %u!\n",
|
||||
private->size, get.size);
|
||||
ret = -EINVAL;
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
module_put(t->me);
|
||||
xt_table_unlock(t);
|
||||
@@ -953,7 +954,7 @@ static int __do_replace(struct net *net, const char *name,
|
||||
void __user *counters_ptr)
|
||||
{
|
||||
int ret;
|
||||
struct arpt_table *t;
|
||||
struct xt_table *t;
|
||||
struct xt_table_info *oldinfo;
|
||||
struct xt_counters *counters;
|
||||
void *loc_cpu_old_entry;
|
||||
@@ -1087,11 +1088,11 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
|
||||
struct xt_counters_info tmp;
|
||||
struct xt_counters *paddc;
|
||||
unsigned int num_counters;
|
||||
char *name;
|
||||
const char *name;
|
||||
int size;
|
||||
void *ptmp;
|
||||
struct arpt_table *t;
|
||||
struct xt_table_info *private;
|
||||
struct xt_table *t;
|
||||
const struct xt_table_info *private;
|
||||
int ret = 0;
|
||||
void *loc_cpu_entry;
|
||||
#ifdef CONFIG_COMPAT
|
||||
@@ -1554,11 +1555,11 @@ out:
|
||||
}
|
||||
|
||||
static int compat_copy_entries_to_user(unsigned int total_size,
|
||||
struct arpt_table *table,
|
||||
struct xt_table *table,
|
||||
void __user *userptr)
|
||||
{
|
||||
struct xt_counters *counters;
|
||||
struct xt_table_info *private = table->private;
|
||||
const struct xt_table_info *private = table->private;
|
||||
void __user *pos;
|
||||
unsigned int size;
|
||||
int ret = 0;
|
||||
@@ -1592,7 +1593,7 @@ static int compat_get_entries(struct net *net,
|
||||
{
|
||||
int ret;
|
||||
struct compat_arpt_get_entries get;
|
||||
struct arpt_table *t;
|
||||
struct xt_table *t;
|
||||
|
||||
if (*len < sizeof(get)) {
|
||||
duprintf("compat_get_entries: %u < %zu\n", *len, sizeof(get));
|
||||
@@ -1609,7 +1610,7 @@ static int compat_get_entries(struct net *net,
|
||||
xt_compat_lock(NF_ARP);
|
||||
t = xt_find_table_lock(net, NF_ARP, get.name);
|
||||
if (t && !IS_ERR(t)) {
|
||||
struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = t->private;
|
||||
struct xt_table_info info;
|
||||
|
||||
duprintf("t->private->number = %u\n", private->number);
|
||||
@@ -1620,7 +1621,7 @@ static int compat_get_entries(struct net *net,
|
||||
} else if (!ret) {
|
||||
duprintf("compat_get_entries: I've got %u not %u!\n",
|
||||
private->size, get.size);
|
||||
ret = -EINVAL;
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
xt_compat_flush_offsets(NF_ARP);
|
||||
module_put(t->me);
|
||||
@@ -1722,9 +1723,8 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct arpt_table *arpt_register_table(struct net *net,
|
||||
struct arpt_table *table,
|
||||
const struct arpt_replace *repl)
|
||||
struct xt_table *arpt_register_table(struct net *net, struct xt_table *table,
|
||||
const struct arpt_replace *repl)
|
||||
{
|
||||
int ret;
|
||||
struct xt_table_info *newinfo;
|
||||
@@ -1766,7 +1766,7 @@ out:
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
void arpt_unregister_table(struct arpt_table *table)
|
||||
void arpt_unregister_table(struct xt_table *table)
|
||||
{
|
||||
struct xt_table_info *private;
|
||||
void *loc_cpu_entry;
|
||||
@@ -1784,7 +1784,7 @@ void arpt_unregister_table(struct arpt_table *table)
|
||||
}
|
||||
|
||||
/* The built-in targets: standard (NULL) and error. */
|
||||
static struct arpt_target arpt_standard_target __read_mostly = {
|
||||
static struct xt_target arpt_standard_target __read_mostly = {
|
||||
.name = ARPT_STANDARD_TARGET,
|
||||
.targetsize = sizeof(int),
|
||||
.family = NF_ARP,
|
||||
@@ -1795,7 +1795,7 @@ static struct arpt_target arpt_standard_target __read_mostly = {
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct arpt_target arpt_error_target __read_mostly = {
|
||||
static struct xt_target arpt_error_target __read_mostly = {
|
||||
.name = ARPT_ERROR_TARGET,
|
||||
.target = arpt_error,
|
||||
.targetsize = ARPT_FUNCTION_MAXNAMELEN,
|
||||
|
@@ -15,7 +15,7 @@ target(struct sk_buff *skb,
|
||||
const void *targinfo)
|
||||
{
|
||||
const struct arpt_mangle *mangle = targinfo;
|
||||
struct arphdr *arp;
|
||||
const struct arphdr *arp;
|
||||
unsigned char *arpptr;
|
||||
int pln, hln;
|
||||
|
||||
@@ -73,8 +73,9 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct arpt_target arpt_mangle_reg __read_mostly = {
|
||||
static struct xt_target arpt_mangle_reg __read_mostly = {
|
||||
.name = "mangle",
|
||||
.family = NF_ARP,
|
||||
.target = target,
|
||||
.targetsize = sizeof(struct arpt_mangle),
|
||||
.checkentry = checkentry,
|
||||
@@ -83,15 +84,12 @@ static struct arpt_target arpt_mangle_reg __read_mostly = {
|
||||
|
||||
static int __init arpt_mangle_init(void)
|
||||
{
|
||||
if (arpt_register_target(&arpt_mangle_reg))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
return xt_register_target(&arpt_mangle_reg);
|
||||
}
|
||||
|
||||
static void __exit arpt_mangle_fini(void)
|
||||
{
|
||||
arpt_unregister_target(&arpt_mangle_reg);
|
||||
xt_unregister_target(&arpt_mangle_reg);
|
||||
}
|
||||
|
||||
module_init(arpt_mangle_init);
|
||||
|
@@ -45,10 +45,10 @@ static struct
|
||||
.term = ARPT_ERROR_INIT,
|
||||
};
|
||||
|
||||
static struct arpt_table packet_filter = {
|
||||
static struct xt_table packet_filter = {
|
||||
.name = "filter",
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
|
||||
.private = NULL,
|
||||
.me = THIS_MODULE,
|
||||
.af = NF_ARP,
|
||||
@@ -70,18 +70,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NF_ARP,
|
||||
.hooknum = NF_ARP_IN,
|
||||
.priority = NF_IP_PRI_FILTER,
|
||||
},
|
||||
{
|
||||
.hook = arpt_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NF_ARP,
|
||||
.hooknum = NF_ARP_OUT,
|
||||
.priority = NF_IP_PRI_FILTER,
|
||||
},
|
||||
{
|
||||
.hook = arpt_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = NF_ARP,
|
||||
.hooknum = NF_ARP_FORWARD,
|
||||
.priority = NF_IP_PRI_FILTER,
|
||||
},
|
||||
};
|
||||
|
||||
|
@@ -296,7 +296,7 @@ static void trace_packet(struct sk_buff *skb,
|
||||
struct ipt_entry *e)
|
||||
{
|
||||
void *table_base;
|
||||
struct ipt_entry *root;
|
||||
const struct ipt_entry *root;
|
||||
char *hookname, *chainname, *comment;
|
||||
unsigned int rulenum = 0;
|
||||
|
||||
@@ -327,7 +327,7 @@ ipt_do_table(struct sk_buff *skb,
|
||||
{
|
||||
static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
|
||||
u_int16_t offset;
|
||||
struct iphdr *ip;
|
||||
const struct iphdr *ip;
|
||||
u_int16_t datalen;
|
||||
bool hotdrop = false;
|
||||
/* Initializing verdict to NF_DROP keeps gcc happy. */
|
||||
@@ -926,7 +926,7 @@ static struct xt_counters * alloc_counters(struct xt_table *table)
|
||||
{
|
||||
unsigned int countersize;
|
||||
struct xt_counters *counters;
|
||||
struct xt_table_info *private = table->private;
|
||||
const struct xt_table_info *private = table->private;
|
||||
|
||||
/* We need atomic snapshot of counters: rest doesn't change
|
||||
(other than comefrom, which userspace doesn't care
|
||||
@@ -953,9 +953,9 @@ copy_entries_to_user(unsigned int total_size,
|
||||
unsigned int off, num;
|
||||
struct ipt_entry *e;
|
||||
struct xt_counters *counters;
|
||||
struct xt_table_info *private = table->private;
|
||||
const struct xt_table_info *private = table->private;
|
||||
int ret = 0;
|
||||
void *loc_cpu_entry;
|
||||
const void *loc_cpu_entry;
|
||||
|
||||
counters = alloc_counters(table);
|
||||
if (IS_ERR(counters))
|
||||
@@ -975,8 +975,8 @@ copy_entries_to_user(unsigned int total_size,
|
||||
/* ... then go back and fix counters and names */
|
||||
for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){
|
||||
unsigned int i;
|
||||
struct ipt_entry_match *m;
|
||||
struct ipt_entry_target *t;
|
||||
const struct ipt_entry_match *m;
|
||||
const struct ipt_entry_target *t;
|
||||
|
||||
e = (struct ipt_entry *)(loc_cpu_entry + off);
|
||||
if (copy_to_user(userptr + off
|
||||
@@ -1116,7 +1116,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
|
||||
"iptable_%s", name);
|
||||
if (t && !IS_ERR(t)) {
|
||||
struct ipt_getinfo info;
|
||||
struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = t->private;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (compat) {
|
||||
@@ -1172,7 +1172,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
|
||||
|
||||
t = xt_find_table_lock(net, AF_INET, get.name);
|
||||
if (t && !IS_ERR(t)) {
|
||||
struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = t->private;
|
||||
duprintf("t->private->number = %u\n", private->number);
|
||||
if (get.size == private->size)
|
||||
ret = copy_entries_to_user(private->size,
|
||||
@@ -1180,7 +1180,7 @@ get_entries(struct net *net, struct ipt_get_entries __user *uptr, int *len)
|
||||
else {
|
||||
duprintf("get_entries: I've got %u not %u!\n",
|
||||
private->size, get.size);
|
||||
ret = -EINVAL;
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
module_put(t->me);
|
||||
xt_table_unlock(t);
|
||||
@@ -1337,11 +1337,11 @@ do_add_counters(struct net *net, void __user *user, unsigned int len, int compat
|
||||
struct xt_counters_info tmp;
|
||||
struct xt_counters *paddc;
|
||||
unsigned int num_counters;
|
||||
char *name;
|
||||
const char *name;
|
||||
int size;
|
||||
void *ptmp;
|
||||
struct xt_table *t;
|
||||
struct xt_table_info *private;
|
||||
const struct xt_table_info *private;
|
||||
int ret = 0;
|
||||
void *loc_cpu_entry;
|
||||
#ifdef CONFIG_COMPAT
|
||||
@@ -1878,11 +1878,11 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table,
|
||||
void __user *userptr)
|
||||
{
|
||||
struct xt_counters *counters;
|
||||
struct xt_table_info *private = table->private;
|
||||
const struct xt_table_info *private = table->private;
|
||||
void __user *pos;
|
||||
unsigned int size;
|
||||
int ret = 0;
|
||||
void *loc_cpu_entry;
|
||||
const void *loc_cpu_entry;
|
||||
unsigned int i = 0;
|
||||
|
||||
counters = alloc_counters(table);
|
||||
@@ -1929,7 +1929,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
|
||||
xt_compat_lock(AF_INET);
|
||||
t = xt_find_table_lock(net, AF_INET, get.name);
|
||||
if (t && !IS_ERR(t)) {
|
||||
struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = t->private;
|
||||
struct xt_table_info info;
|
||||
duprintf("t->private->number = %u\n", private->number);
|
||||
ret = compat_table_info(private, &info);
|
||||
@@ -1939,7 +1939,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
|
||||
} else if (!ret) {
|
||||
duprintf("compat_get_entries: I've got %u not %u!\n",
|
||||
private->size, get.size);
|
||||
ret = -EINVAL;
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
xt_compat_flush_offsets(AF_INET);
|
||||
module_put(t->me);
|
||||
@@ -2130,7 +2130,8 @@ icmp_match(const struct sk_buff *skb,
|
||||
unsigned int protoff,
|
||||
bool *hotdrop)
|
||||
{
|
||||
struct icmphdr _icmph, *ic;
|
||||
const struct icmphdr *ic;
|
||||
struct icmphdr _icmph;
|
||||
const struct ipt_icmp *icmpinfo = matchinfo;
|
||||
|
||||
/* Must not be a fragment. */
|
||||
|
@@ -144,7 +144,7 @@ clusterip_config_init_nodelist(struct clusterip_config *c,
|
||||
}
|
||||
|
||||
static struct clusterip_config *
|
||||
clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip,
|
||||
clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct clusterip_config *c;
|
||||
@@ -333,7 +333,7 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in,
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||
nf_ct_dump_tuple_ip(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
|
||||
#endif
|
||||
pr_debug("hash=%u ct_hash=%u ", hash, ct->mark);
|
||||
if (!clusterip_responsible(cipinfo->config, hash)) {
|
||||
@@ -418,7 +418,7 @@ clusterip_tg_check(const char *tablename, const void *e_void,
|
||||
/* drop reference count of cluster config when rule is deleted */
|
||||
static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
|
||||
{
|
||||
struct ipt_clusterip_tgt_info *cipinfo = targinfo;
|
||||
const struct ipt_clusterip_tgt_info *cipinfo = targinfo;
|
||||
|
||||
/* if no more entries are referencing the config, remove it
|
||||
* from the list and destroy the proc entry */
|
||||
@@ -567,7 +567,7 @@ struct clusterip_seq_position {
|
||||
|
||||
static void *clusterip_seq_start(struct seq_file *s, loff_t *pos)
|
||||
{
|
||||
struct proc_dir_entry *pde = s->private;
|
||||
const struct proc_dir_entry *pde = s->private;
|
||||
struct clusterip_config *c = pde->data;
|
||||
unsigned int weight;
|
||||
u_int32_t local_nodes;
|
||||
@@ -594,7 +594,7 @@ static void *clusterip_seq_start(struct seq_file *s, loff_t *pos)
|
||||
|
||||
static void *clusterip_seq_next(struct seq_file *s, void *v, loff_t *pos)
|
||||
{
|
||||
struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v;
|
||||
struct clusterip_seq_position *idx = v;
|
||||
|
||||
*pos = ++idx->pos;
|
||||
if (*pos >= idx->weight) {
|
||||
@@ -613,7 +613,7 @@ static void clusterip_seq_stop(struct seq_file *s, void *v)
|
||||
|
||||
static int clusterip_seq_show(struct seq_file *s, void *v)
|
||||
{
|
||||
struct clusterip_seq_position *idx = (struct clusterip_seq_position *)v;
|
||||
struct clusterip_seq_position *idx = v;
|
||||
|
||||
if (idx->pos != 0)
|
||||
seq_putc(s, ',');
|
||||
@@ -669,7 +669,7 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input,
|
||||
{
|
||||
#define PROC_WRITELEN 10
|
||||
char buffer[PROC_WRITELEN+1];
|
||||
struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
|
||||
const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
|
||||
struct clusterip_config *c = pde->data;
|
||||
unsigned long nodenum;
|
||||
|
||||
|
@@ -100,7 +100,7 @@ ecn_tg_check(const char *tablename, const void *e_void,
|
||||
const struct xt_target *target, void *targinfo,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
const struct ipt_ECN_info *einfo = (struct ipt_ECN_info *)targinfo;
|
||||
const struct ipt_ECN_info *einfo = targinfo;
|
||||
const struct ipt_entry *e = e_void;
|
||||
|
||||
if (einfo->operation & IPT_ECN_OP_MASK) {
|
||||
|
@@ -76,7 +76,8 @@ static void dump_packet(const struct nf_loginfo *info,
|
||||
|
||||
if ((logflags & IPT_LOG_IPOPT)
|
||||
&& ih->ihl * 4 > sizeof(struct iphdr)) {
|
||||
unsigned char _opt[4 * 15 - sizeof(struct iphdr)], *op;
|
||||
const unsigned char *op;
|
||||
unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
|
||||
unsigned int i, optsize;
|
||||
|
||||
optsize = ih->ihl * 4 - sizeof(struct iphdr);
|
||||
@@ -338,12 +339,16 @@ static void dump_packet(const struct nf_loginfo *info,
|
||||
if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
|
||||
read_lock_bh(&skb->sk->sk_callback_lock);
|
||||
if (skb->sk->sk_socket && skb->sk->sk_socket->file)
|
||||
printk("UID=%u GID=%u",
|
||||
printk("UID=%u GID=%u ",
|
||||
skb->sk->sk_socket->file->f_uid,
|
||||
skb->sk->sk_socket->file->f_gid);
|
||||
read_unlock_bh(&skb->sk->sk_callback_lock);
|
||||
}
|
||||
|
||||
/* Max length: 16 "MARK=0xFFFFFFFF " */
|
||||
if (!iphoff && skb->mark)
|
||||
printk("MARK=0x%x ", skb->mark);
|
||||
|
||||
/* Proto Max log string length */
|
||||
/* IP: 40+46+6+11+127 = 230 */
|
||||
/* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
|
||||
|
@@ -35,8 +35,10 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv4");
|
||||
static void send_reset(struct sk_buff *oldskb, int hook)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
struct iphdr *oiph, *niph;
|
||||
struct tcphdr _otcph, *oth, *tcph;
|
||||
const struct iphdr *oiph;
|
||||
struct iphdr *niph;
|
||||
const struct tcphdr *oth;
|
||||
struct tcphdr _otcph, *tcph;
|
||||
unsigned int addr_type;
|
||||
|
||||
/* IP header checks: fragment. */
|
||||
|
@@ -340,7 +340,7 @@ static void *recent_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct recent_iter_state *st = seq->private;
|
||||
struct recent_table *t = st->table;
|
||||
const struct recent_table *t = st->table;
|
||||
struct recent_entry *e = v;
|
||||
struct list_head *head = e->list.next;
|
||||
|
||||
@@ -361,7 +361,7 @@ static void recent_seq_stop(struct seq_file *s, void *v)
|
||||
|
||||
static int recent_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct recent_entry *e = v;
|
||||
const struct recent_entry *e = v;
|
||||
unsigned int i;
|
||||
|
||||
i = (e->index - 1) % ip_pkt_list_tot;
|
||||
@@ -396,7 +396,7 @@ static int recent_seq_open(struct inode *inode, struct file *file)
|
||||
static ssize_t recent_proc_write(struct file *file, const char __user *input,
|
||||
size_t size, loff_t *loff)
|
||||
{
|
||||
struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
|
||||
const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
|
||||
struct recent_table *t = pde->data;
|
||||
struct recent_entry *e;
|
||||
char buf[sizeof("+255.255.255.255")], *c = buf;
|
||||
|
@@ -56,12 +56,23 @@ static struct
|
||||
static struct xt_table packet_filter = {
|
||||
.name = "filter",
|
||||
.valid_hooks = FILTER_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
static unsigned int
|
||||
ipt_local_in_hook(unsigned int hook,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_local_in_net(in, out)->ipv4.iptable_filter);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_hook(unsigned int hook,
|
||||
struct sk_buff *skb,
|
||||
@@ -69,7 +80,8 @@ ipt_hook(unsigned int hook,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter);
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_forward_net(in, out)->ipv4.iptable_filter);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
@@ -88,12 +100,13 @@ ipt_local_out_hook(unsigned int hook,
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_filter);
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_local_out_net(in, out)->ipv4.iptable_filter);
|
||||
}
|
||||
|
||||
static struct nf_hook_ops ipt_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ipt_hook,
|
||||
.hook = ipt_local_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
|
@@ -67,20 +67,54 @@ static struct
|
||||
static struct xt_table packet_mangler = {
|
||||
.name = "mangle",
|
||||
.valid_hooks = MANGLE_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.lock = __RW_LOCK_UNLOCKED(packet_mangler.lock),
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
|
||||
/* The work comes in here from netfilter.c. */
|
||||
static unsigned int
|
||||
ipt_route_hook(unsigned int hook,
|
||||
ipt_pre_routing_hook(unsigned int hook,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_pre_routing_net(in, out)->ipv4.iptable_mangle);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_post_routing_hook(unsigned int hook,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_post_routing_net(in, out)->ipv4.iptable_mangle);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_local_in_hook(unsigned int hook,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_local_in_net(in, out)->ipv4.iptable_mangle);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
ipt_forward_hook(unsigned int hook,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle);
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_forward_net(in, out)->ipv4.iptable_mangle);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
@@ -112,7 +146,8 @@ ipt_local_hook(unsigned int hook,
|
||||
daddr = iph->daddr;
|
||||
tos = iph->tos;
|
||||
|
||||
ret = ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_mangle);
|
||||
ret = ipt_do_table(skb, hook, in, out,
|
||||
nf_local_out_net(in, out)->ipv4.iptable_mangle);
|
||||
/* Reroute for ANY change. */
|
||||
if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
|
||||
iph = ip_hdr(skb);
|
||||
@@ -130,21 +165,21 @@ ipt_local_hook(unsigned int hook,
|
||||
|
||||
static struct nf_hook_ops ipt_ops[] __read_mostly = {
|
||||
{
|
||||
.hook = ipt_route_hook,
|
||||
.hook = ipt_pre_routing_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_PRE_ROUTING,
|
||||
.priority = NF_IP_PRI_MANGLE,
|
||||
},
|
||||
{
|
||||
.hook = ipt_route_hook,
|
||||
.hook = ipt_local_in_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_MANGLE,
|
||||
},
|
||||
{
|
||||
.hook = ipt_route_hook,
|
||||
.hook = ipt_forward_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_FORWARD,
|
||||
@@ -158,7 +193,7 @@ static struct nf_hook_ops ipt_ops[] __read_mostly = {
|
||||
.priority = NF_IP_PRI_MANGLE,
|
||||
},
|
||||
{
|
||||
.hook = ipt_route_hook,
|
||||
.hook = ipt_post_routing_hook,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
|
@@ -39,7 +39,7 @@ static struct
|
||||
static struct xt_table packet_raw = {
|
||||
.name = "raw",
|
||||
.valid_hooks = RAW_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.lock = __RW_LOCK_UNLOCKED(packet_raw.lock),
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
@@ -52,7 +52,8 @@ ipt_hook(unsigned int hook,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw);
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_pre_routing_net(in, out)->ipv4.iptable_raw);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
@@ -70,7 +71,8 @@ ipt_local_hook(unsigned int hook,
|
||||
"packet.\n");
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
return ipt_do_table(skb, hook, in, out, init_net.ipv4.iptable_raw);
|
||||
return ipt_do_table(skb, hook, in, out,
|
||||
nf_local_out_net(in, out)->ipv4.iptable_raw);
|
||||
}
|
||||
|
||||
/* 'raw' is the very first table. */
|
||||
|
@@ -23,30 +23,36 @@
|
||||
#include <net/netfilter/nf_conntrack_l3proto.h>
|
||||
#include <net/netfilter/nf_conntrack_core.h>
|
||||
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
|
||||
#include <net/netfilter/nf_nat_helper.h>
|
||||
|
||||
static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
|
||||
struct nf_conn *ct,
|
||||
enum ip_conntrack_info ctinfo);
|
||||
EXPORT_SYMBOL_GPL(nf_nat_seq_adjust_hook);
|
||||
|
||||
static bool ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
const __be32 *ap;
|
||||
__be32 _addrs[2];
|
||||
ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
|
||||
sizeof(u_int32_t) * 2, _addrs);
|
||||
if (ap == NULL)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
tuple->src.u3.ip = ap[0];
|
||||
tuple->dst.u3.ip = ap[1];
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_conntrack_tuple *orig)
|
||||
static bool ipv4_invert_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_conntrack_tuple *orig)
|
||||
{
|
||||
tuple->src.u3.ip = orig->dst.u3.ip;
|
||||
tuple->dst.u3.ip = orig->src.u3.ip;
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ipv4_print_tuple(struct seq_file *s,
|
||||
@@ -100,36 +106,42 @@ static unsigned int ipv4_confirm(unsigned int hooknum,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
/* We've seen it coming out the other side: confirm it */
|
||||
return nf_conntrack_confirm(skb);
|
||||
}
|
||||
|
||||
static unsigned int ipv4_conntrack_help(unsigned int hooknum,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
const struct nf_conn_help *help;
|
||||
const struct nf_conntrack_helper *helper;
|
||||
unsigned int ret;
|
||||
|
||||
/* This is where we call the helper: as the packet goes out. */
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (!ct || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)
|
||||
return NF_ACCEPT;
|
||||
goto out;
|
||||
|
||||
help = nfct_help(ct);
|
||||
if (!help)
|
||||
return NF_ACCEPT;
|
||||
goto out;
|
||||
|
||||
/* rcu_read_lock()ed by nf_hook_slow */
|
||||
helper = rcu_dereference(help->helper);
|
||||
if (!helper)
|
||||
return NF_ACCEPT;
|
||||
return helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
|
||||
ct, ctinfo);
|
||||
goto out;
|
||||
|
||||
ret = helper->help(skb, skb_network_offset(skb) + ip_hdrlen(skb),
|
||||
ct, ctinfo);
|
||||
if (ret != NF_ACCEPT)
|
||||
return ret;
|
||||
|
||||
if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
|
||||
typeof(nf_nat_seq_adjust_hook) seq_adjust;
|
||||
|
||||
seq_adjust = rcu_dereference(nf_nat_seq_adjust_hook);
|
||||
if (!seq_adjust || !seq_adjust(skb, ct, ctinfo))
|
||||
return NF_DROP;
|
||||
}
|
||||
out:
|
||||
/* We've seen it coming out the other side: confirm it */
|
||||
return nf_conntrack_confirm(skb);
|
||||
}
|
||||
|
||||
static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
|
||||
@@ -210,20 +222,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
|
||||
.hooknum = NF_INET_LOCAL_OUT,
|
||||
.priority = NF_IP_PRI_CONNTRACK,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_conntrack_help,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_CONNTRACK_HELPER,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_conntrack_help,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_CONNTRACK_HELPER,
|
||||
},
|
||||
{
|
||||
.hook = ipv4_confirm,
|
||||
.owner = THIS_MODULE,
|
||||
|
@@ -106,21 +106,16 @@ static int ct_seq_show(struct seq_file *s, void *v)
|
||||
/* we only want to print DIR_ORIGINAL */
|
||||
if (NF_CT_DIRECTION(hash))
|
||||
return 0;
|
||||
if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num != AF_INET)
|
||||
if (nf_ct_l3num(ct) != AF_INET)
|
||||
return 0;
|
||||
|
||||
l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
|
||||
.tuple.src.l3num);
|
||||
l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
|
||||
NF_CT_ASSERT(l3proto);
|
||||
l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
|
||||
.tuple.src.l3num,
|
||||
ct->tuplehash[IP_CT_DIR_ORIGINAL]
|
||||
.tuple.dst.protonum);
|
||||
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
|
||||
NF_CT_ASSERT(l4proto);
|
||||
|
||||
if (seq_printf(s, "%-8s %u %ld ",
|
||||
l4proto->name,
|
||||
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
|
||||
l4proto->name, nf_ct_protonum(ct),
|
||||
timer_pending(&ct->timeout)
|
||||
? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
|
||||
return -ENOSPC;
|
||||
|
@@ -22,22 +22,21 @@
|
||||
|
||||
static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
|
||||
|
||||
static int icmp_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
static bool icmp_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
{
|
||||
const struct icmphdr *hp;
|
||||
struct icmphdr _hdr;
|
||||
|
||||
hp = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
|
||||
if (hp == NULL)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
tuple->dst.u.icmp.type = hp->type;
|
||||
tuple->src.u.icmp.id = hp->un.echo.id;
|
||||
tuple->dst.u.icmp.code = hp->code;
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Add 1; spaces filled with 0. */
|
||||
@@ -52,17 +51,17 @@ static const u_int8_t invmap[] = {
|
||||
[ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1
|
||||
};
|
||||
|
||||
static int icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_conntrack_tuple *orig)
|
||||
static bool icmp_invert_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_conntrack_tuple *orig)
|
||||
{
|
||||
if (orig->dst.u.icmp.type >= sizeof(invmap)
|
||||
|| !invmap[orig->dst.u.icmp.type])
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
tuple->src.u.icmp.id = orig->src.u.icmp.id;
|
||||
tuple->dst.u.icmp.type = invmap[orig->dst.u.icmp.type] - 1;
|
||||
tuple->dst.u.icmp.code = orig->dst.u.icmp.code;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Print out the per-protocol part of the tuple. */
|
||||
@@ -101,8 +100,8 @@ static int icmp_packet(struct nf_conn *ct,
|
||||
}
|
||||
|
||||
/* Called when a new connection for this protocol found. */
|
||||
static int icmp_new(struct nf_conn *ct,
|
||||
const struct sk_buff *skb, unsigned int dataoff)
|
||||
static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
unsigned int dataoff)
|
||||
{
|
||||
static const u_int8_t valid_new[] = {
|
||||
[ICMP_ECHO] = 1,
|
||||
@@ -116,11 +115,11 @@ static int icmp_new(struct nf_conn *ct,
|
||||
/* Can't create a new ICMP `conn' with this. */
|
||||
pr_debug("icmp: can't create new conn with type %u\n",
|
||||
ct->tuplehash[0].tuple.dst.u.icmp.type);
|
||||
NF_CT_DUMP_TUPLE(&ct->tuplehash[0].tuple);
|
||||
return 0;
|
||||
nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple);
|
||||
return false;
|
||||
}
|
||||
atomic_set(&ct->proto.icmp.count, 0);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
|
||||
|
@@ -150,9 +150,9 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range)
|
||||
{
|
||||
unsigned int h = hash_by_src(tuple);
|
||||
struct nf_conn_nat *nat;
|
||||
struct nf_conn *ct;
|
||||
struct hlist_node *n;
|
||||
const struct nf_conn_nat *nat;
|
||||
const struct nf_conn *ct;
|
||||
const struct hlist_node *n;
|
||||
|
||||
rcu_read_lock();
|
||||
hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) {
|
||||
@@ -349,7 +349,7 @@ nf_nat_setup_info(struct nf_conn *ct,
|
||||
EXPORT_SYMBOL(nf_nat_setup_info);
|
||||
|
||||
/* Returns true if succeeded. */
|
||||
static int
|
||||
static bool
|
||||
manip_pkt(u_int16_t proto,
|
||||
struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
@@ -360,7 +360,7 @@ manip_pkt(u_int16_t proto,
|
||||
const struct nf_nat_protocol *p;
|
||||
|
||||
if (!skb_make_writable(skb, iphdroff + sizeof(*iph)))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
iph = (void *)skb->data + iphdroff;
|
||||
|
||||
@@ -369,7 +369,7 @@ manip_pkt(u_int16_t proto,
|
||||
/* rcu_read_lock()ed by nf_hook_slow */
|
||||
p = __nf_nat_proto_find(proto);
|
||||
if (!p->manip_pkt(skb, iphdroff, target, maniptype))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
iph = (void *)skb->data + iphdroff;
|
||||
|
||||
@@ -380,7 +380,7 @@ manip_pkt(u_int16_t proto,
|
||||
csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
|
||||
iph->daddr = target->dst.u3.ip;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Do packet manipulations according to nf_nat_setup_info. */
|
||||
@@ -426,7 +426,7 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
|
||||
struct icmphdr icmp;
|
||||
struct iphdr ip;
|
||||
} *inside;
|
||||
struct nf_conntrack_l4proto *l4proto;
|
||||
const struct nf_conntrack_l4proto *l4proto;
|
||||
struct nf_conntrack_tuple inner, target;
|
||||
int hdrlen = ip_hdrlen(skb);
|
||||
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
|
||||
@@ -544,46 +544,6 @@ void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto)
|
||||
}
|
||||
EXPORT_SYMBOL(nf_nat_protocol_unregister);
|
||||
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
int
|
||||
nf_nat_port_range_to_nlattr(struct sk_buff *skb,
|
||||
const struct nf_nat_range *range)
|
||||
{
|
||||
NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MIN, range->min.tcp.port);
|
||||
NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MAX, range->max.tcp.port);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_nat_port_nlattr_to_range);
|
||||
|
||||
int
|
||||
nf_nat_port_nlattr_to_range(struct nlattr *tb[], struct nf_nat_range *range)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* we have to return whether we actually parsed something or not */
|
||||
|
||||
if (tb[CTA_PROTONAT_PORT_MIN]) {
|
||||
ret = 1;
|
||||
range->min.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MIN]);
|
||||
}
|
||||
|
||||
if (!tb[CTA_PROTONAT_PORT_MAX]) {
|
||||
if (ret)
|
||||
range->max.tcp.port = range->min.tcp.port;
|
||||
} else {
|
||||
ret = 1;
|
||||
range->max.tcp.port = nla_get_be16(tb[CTA_PROTONAT_PORT_MAX]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nlattr);
|
||||
#endif
|
||||
|
||||
/* Noone using conntrack by the time this called. */
|
||||
static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
|
||||
{
|
||||
@@ -660,6 +620,9 @@ static int __init nf_nat_init(void)
|
||||
nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
|
||||
|
||||
l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
|
||||
|
||||
BUG_ON(nf_nat_seq_adjust_hook != NULL);
|
||||
rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
|
||||
return 0;
|
||||
|
||||
cleanup_extend:
|
||||
@@ -686,6 +649,8 @@ static void __exit nf_nat_cleanup(void)
|
||||
nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
|
||||
nf_ct_l3proto_put(l3proto);
|
||||
nf_ct_extend_unregister(&nat_extend);
|
||||
rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
|
||||
synchronize_net();
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -416,7 +416,6 @@ nf_nat_seq_adjust(struct sk_buff *skb,
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL(nf_nat_seq_adjust);
|
||||
|
||||
/* Setup NAT on this expected conntrack so it follows master. */
|
||||
/* If we fail to get a free NAT slot, we'll get dropped on confirm */
|
||||
|
@@ -72,7 +72,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
|
||||
}
|
||||
|
||||
pr_debug("trying to unexpect other dir: ");
|
||||
NF_CT_DUMP_TUPLE(&t);
|
||||
nf_ct_dump_tuple_ip(&t);
|
||||
other_exp = nf_ct_expect_find_get(&t);
|
||||
if (other_exp) {
|
||||
nf_ct_unexpect_related(other_exp);
|
||||
|
120
net/ipv4/netfilter/nf_nat_proto_common.c
Normal file
120
net/ipv4/netfilter/nf_nat_proto_common.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
|
||||
* (C) 2008 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/types.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/ip.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
#include <net/netfilter/nf_nat_core.h>
|
||||
#include <net/netfilter/nf_nat_rule.h>
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
|
||||
bool nf_nat_proto_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
const union nf_conntrack_man_proto *max)
|
||||
{
|
||||
__be16 port;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
port = tuple->src.u.all;
|
||||
else
|
||||
port = tuple->dst.u.all;
|
||||
|
||||
return ntohs(port) >= ntohs(min->all) &&
|
||||
ntohs(port) <= ntohs(max->all);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_nat_proto_in_range);
|
||||
|
||||
bool nf_nat_proto_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct,
|
||||
u_int16_t *rover)
|
||||
{
|
||||
unsigned int range_size, min, i;
|
||||
__be16 *portptr;
|
||||
u_int16_t off;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
portptr = &tuple->src.u.all;
|
||||
else
|
||||
portptr = &tuple->dst.u.all;
|
||||
|
||||
/* If no range specified... */
|
||||
if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
|
||||
/* If it's dst rewrite, can't change port */
|
||||
if (maniptype == IP_NAT_MANIP_DST)
|
||||
return false;
|
||||
|
||||
if (ntohs(*portptr) < 1024) {
|
||||
/* Loose convention: >> 512 is credential passing */
|
||||
if (ntohs(*portptr) < 512) {
|
||||
min = 1;
|
||||
range_size = 511 - min + 1;
|
||||
} else {
|
||||
min = 600;
|
||||
range_size = 1023 - min + 1;
|
||||
}
|
||||
} else {
|
||||
min = 1024;
|
||||
range_size = 65535 - 1024 + 1;
|
||||
}
|
||||
} else {
|
||||
min = ntohs(range->min.all);
|
||||
range_size = ntohs(range->max.all) - min + 1;
|
||||
}
|
||||
|
||||
off = *rover;
|
||||
if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
|
||||
off = net_random();
|
||||
|
||||
for (i = 0; i < range_size; i++, off++) {
|
||||
*portptr = htons(min + off % range_size);
|
||||
if (nf_nat_used_tuple(tuple, ct))
|
||||
continue;
|
||||
if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM))
|
||||
*rover = off;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_nat_proto_unique_tuple);
|
||||
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
int nf_nat_proto_range_to_nlattr(struct sk_buff *skb,
|
||||
const struct nf_nat_range *range)
|
||||
{
|
||||
NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MIN, range->min.all);
|
||||
NLA_PUT_BE16(skb, CTA_PROTONAT_PORT_MAX, range->max.all);
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_nat_proto_nlattr_to_range);
|
||||
|
||||
int nf_nat_proto_nlattr_to_range(struct nlattr *tb[],
|
||||
struct nf_nat_range *range)
|
||||
{
|
||||
if (tb[CTA_PROTONAT_PORT_MIN]) {
|
||||
range->min.all = nla_get_be16(tb[CTA_PROTONAT_PORT_MIN]);
|
||||
range->max.all = range->min.tcp.port;
|
||||
range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
|
||||
}
|
||||
if (tb[CTA_PROTONAT_PORT_MAX]) {
|
||||
range->max.all = nla_get_be16(tb[CTA_PROTONAT_PORT_MAX]);
|
||||
range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nf_nat_proto_range_to_nlattr);
|
||||
#endif
|
108
net/ipv4/netfilter/nf_nat_proto_dccp.c
Normal file
108
net/ipv4/netfilter/nf_nat_proto_dccp.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* DCCP NAT protocol helper
|
||||
*
|
||||
* Copyright (c) 2005, 2006. 2008 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/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/dccp.h>
|
||||
|
||||
#include <net/netfilter/nf_conntrack.h>
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
|
||||
static u_int16_t dccp_port_rover;
|
||||
|
||||
static bool
|
||||
dccp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct)
|
||||
{
|
||||
return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
|
||||
&dccp_port_rover);
|
||||
}
|
||||
|
||||
static bool
|
||||
dccp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
const struct iphdr *iph = (const void *)(skb->data + iphdroff);
|
||||
struct dccp_hdr *hdr;
|
||||
unsigned int hdroff = iphdroff + iph->ihl * 4;
|
||||
__be32 oldip, newip;
|
||||
__be16 *portptr, oldport, newport;
|
||||
int hdrsize = 8; /* DCCP connection tracking guarantees this much */
|
||||
|
||||
if (skb->len >= hdroff + sizeof(struct dccp_hdr))
|
||||
hdrsize = sizeof(struct dccp_hdr);
|
||||
|
||||
if (!skb_make_writable(skb, hdroff + hdrsize))
|
||||
return false;
|
||||
|
||||
iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
hdr = (struct dccp_hdr *)(skb->data + hdroff);
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC) {
|
||||
oldip = iph->saddr;
|
||||
newip = tuple->src.u3.ip;
|
||||
newport = tuple->src.u.dccp.port;
|
||||
portptr = &hdr->dccph_sport;
|
||||
} else {
|
||||
oldip = iph->daddr;
|
||||
newip = tuple->dst.u3.ip;
|
||||
newport = tuple->dst.u.dccp.port;
|
||||
portptr = &hdr->dccph_dport;
|
||||
}
|
||||
|
||||
oldport = *portptr;
|
||||
*portptr = newport;
|
||||
|
||||
if (hdrsize < sizeof(*hdr))
|
||||
return true;
|
||||
|
||||
inet_proto_csum_replace4(&hdr->dccph_checksum, skb, oldip, newip, 1);
|
||||
inet_proto_csum_replace2(&hdr->dccph_checksum, skb, oldport, newport,
|
||||
0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct nf_nat_protocol nf_nat_protocol_dccp = {
|
||||
.protonum = IPPROTO_DCCP,
|
||||
.me = THIS_MODULE,
|
||||
.manip_pkt = dccp_manip_pkt,
|
||||
.in_range = nf_nat_proto_in_range,
|
||||
.unique_tuple = dccp_unique_tuple,
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
.range_to_nlattr = nf_nat_proto_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_proto_nlattr_to_range,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init nf_nat_proto_dccp_init(void)
|
||||
{
|
||||
return nf_nat_protocol_register(&nf_nat_protocol_dccp);
|
||||
}
|
||||
|
||||
static void __exit nf_nat_proto_dccp_fini(void)
|
||||
{
|
||||
nf_nat_protocol_unregister(&nf_nat_protocol_dccp);
|
||||
}
|
||||
|
||||
module_init(nf_nat_proto_dccp_init);
|
||||
module_exit(nf_nat_proto_dccp_fini);
|
||||
|
||||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
|
||||
MODULE_DESCRIPTION("DCCP NAT protocol helper");
|
||||
MODULE_LICENSE("GPL");
|
@@ -36,26 +36,8 @@ MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
|
||||
MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
|
||||
|
||||
/* is key in given range between min and max */
|
||||
static int
|
||||
gre_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
const union nf_conntrack_man_proto *max)
|
||||
{
|
||||
__be16 key;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
key = tuple->src.u.gre.key;
|
||||
else
|
||||
key = tuple->dst.u.gre.key;
|
||||
|
||||
return ntohs(key) >= ntohs(min->gre.key) &&
|
||||
ntohs(key) <= ntohs(max->gre.key);
|
||||
}
|
||||
|
||||
/* generate unique tuple ... */
|
||||
static int
|
||||
static bool
|
||||
gre_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
@@ -68,7 +50,7 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
/* If there is no master conntrack we are not PPTP,
|
||||
do not change tuples */
|
||||
if (!ct->master)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
keyptr = &tuple->src.u.gre.key;
|
||||
@@ -89,20 +71,20 @@ gre_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
for (i = 0; i < range_size; i++, key++) {
|
||||
*keyptr = htons(min + key % range_size);
|
||||
if (!nf_nat_used_tuple(tuple, ct))
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
pr_debug("%p: no NAT mapping\n", ct);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* manipulate a GRE packet according to maniptype */
|
||||
static int
|
||||
static bool
|
||||
gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
struct gre_hdr *greh;
|
||||
const struct gre_hdr *greh;
|
||||
struct gre_hdr_pptp *pgreh;
|
||||
const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
unsigned int hdroff = iphdroff + iph->ihl * 4;
|
||||
@@ -110,7 +92,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
|
||||
/* pgreh includes two optional 32bit fields which are not required
|
||||
* to be there. That's where the magic '8' comes from */
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*pgreh) - 8))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
greh = (void *)skb->data + hdroff;
|
||||
pgreh = (struct gre_hdr_pptp *)greh;
|
||||
@@ -118,7 +100,7 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
|
||||
/* we only have destination manip of a packet, since 'source key'
|
||||
* is not present in the packet itself */
|
||||
if (maniptype != IP_NAT_MANIP_DST)
|
||||
return 1;
|
||||
return true;
|
||||
switch (greh->version) {
|
||||
case GRE_VERSION_1701:
|
||||
/* We do not currently NAT any GREv0 packets.
|
||||
@@ -130,21 +112,20 @@ gre_manip_pkt(struct sk_buff *skb, unsigned int iphdroff,
|
||||
break;
|
||||
default:
|
||||
pr_debug("can't nat unknown GRE version\n");
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct nf_nat_protocol gre = {
|
||||
.name = "GRE",
|
||||
.protonum = IPPROTO_GRE,
|
||||
.me = THIS_MODULE,
|
||||
.manip_pkt = gre_manip_pkt,
|
||||
.in_range = gre_in_range,
|
||||
.in_range = nf_nat_proto_in_range,
|
||||
.unique_tuple = gre_unique_tuple,
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
.range_to_nlattr = nf_nat_port_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_port_nlattr_to_range,
|
||||
.range_to_nlattr = nf_nat_proto_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_proto_nlattr_to_range,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#include <net/netfilter/nf_nat_rule.h>
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
|
||||
static int
|
||||
static bool
|
||||
icmp_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
@@ -27,7 +27,7 @@ icmp_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
icmp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
@@ -46,12 +46,12 @@ icmp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) +
|
||||
(id % range_size));
|
||||
if (!nf_nat_used_tuple(tuple, ct))
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
icmp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
@@ -62,24 +62,23 @@ icmp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int hdroff = iphdroff + iph->ihl*4;
|
||||
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
hdr = (struct icmphdr *)(skb->data + hdroff);
|
||||
inet_proto_csum_replace2(&hdr->checksum, skb,
|
||||
hdr->un.echo.id, tuple->src.u.icmp.id, 0);
|
||||
hdr->un.echo.id = tuple->src.u.icmp.id;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct nf_nat_protocol nf_nat_protocol_icmp = {
|
||||
.name = "ICMP",
|
||||
.protonum = IPPROTO_ICMP,
|
||||
.me = THIS_MODULE,
|
||||
.manip_pkt = icmp_manip_pkt,
|
||||
.in_range = icmp_in_range,
|
||||
.unique_tuple = icmp_unique_tuple,
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
.range_to_nlattr = nf_nat_port_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_port_nlattr_to_range,
|
||||
.range_to_nlattr = nf_nat_proto_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_proto_nlattr_to_range,
|
||||
#endif
|
||||
};
|
||||
|
96
net/ipv4/netfilter/nf_nat_proto_sctp.c
Normal file
96
net/ipv4/netfilter/nf_nat_proto_sctp.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2008 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/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/sctp.h>
|
||||
#include <net/sctp/checksum.h>
|
||||
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
|
||||
static u_int16_t nf_sctp_port_rover;
|
||||
|
||||
static bool
|
||||
sctp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct)
|
||||
{
|
||||
return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
|
||||
&nf_sctp_port_rover);
|
||||
}
|
||||
|
||||
static bool
|
||||
sctp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
sctp_sctphdr_t *hdr;
|
||||
unsigned int hdroff = iphdroff + iph->ihl*4;
|
||||
__be32 oldip, newip;
|
||||
u32 crc32;
|
||||
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
||||
return false;
|
||||
|
||||
iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
hdr = (struct sctphdr *)(skb->data + hdroff);
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC) {
|
||||
/* Get rid of src ip and src pt */
|
||||
oldip = iph->saddr;
|
||||
newip = tuple->src.u3.ip;
|
||||
hdr->source = tuple->src.u.sctp.port;
|
||||
} else {
|
||||
/* Get rid of dst ip and dst pt */
|
||||
oldip = iph->daddr;
|
||||
newip = tuple->dst.u3.ip;
|
||||
hdr->dest = tuple->dst.u.sctp.port;
|
||||
}
|
||||
|
||||
crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff);
|
||||
for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
|
||||
crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb),
|
||||
crc32);
|
||||
crc32 = sctp_end_cksum(crc32);
|
||||
hdr->checksum = htonl(crc32);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct nf_nat_protocol nf_nat_protocol_sctp = {
|
||||
.protonum = IPPROTO_SCTP,
|
||||
.me = THIS_MODULE,
|
||||
.manip_pkt = sctp_manip_pkt,
|
||||
.in_range = nf_nat_proto_in_range,
|
||||
.unique_tuple = sctp_unique_tuple,
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
.range_to_nlattr = nf_nat_proto_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_proto_nlattr_to_range,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init nf_nat_proto_sctp_init(void)
|
||||
{
|
||||
return nf_nat_protocol_register(&nf_nat_protocol_sctp);
|
||||
}
|
||||
|
||||
static void __exit nf_nat_proto_sctp_exit(void)
|
||||
{
|
||||
nf_nat_protocol_unregister(&nf_nat_protocol_sctp);
|
||||
}
|
||||
|
||||
module_init(nf_nat_proto_sctp_init);
|
||||
module_exit(nf_nat_proto_sctp_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SCTP NAT protocol helper");
|
||||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
|
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
|
||||
@@ -19,75 +18,19 @@
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
#include <net/netfilter/nf_nat_core.h>
|
||||
|
||||
static int
|
||||
tcp_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
const union nf_conntrack_man_proto *max)
|
||||
{
|
||||
__be16 port;
|
||||
static u_int16_t tcp_port_rover;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
port = tuple->src.u.tcp.port;
|
||||
else
|
||||
port = tuple->dst.u.tcp.port;
|
||||
|
||||
return ntohs(port) >= ntohs(min->tcp.port) &&
|
||||
ntohs(port) <= ntohs(max->tcp.port);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
tcp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct)
|
||||
{
|
||||
static u_int16_t port;
|
||||
__be16 *portptr;
|
||||
unsigned int range_size, min, i;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
portptr = &tuple->src.u.tcp.port;
|
||||
else
|
||||
portptr = &tuple->dst.u.tcp.port;
|
||||
|
||||
/* If no range specified... */
|
||||
if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
|
||||
/* If it's dst rewrite, can't change port */
|
||||
if (maniptype == IP_NAT_MANIP_DST)
|
||||
return 0;
|
||||
|
||||
/* Map privileged onto privileged. */
|
||||
if (ntohs(*portptr) < 1024) {
|
||||
/* Loose convention: >> 512 is credential passing */
|
||||
if (ntohs(*portptr)<512) {
|
||||
min = 1;
|
||||
range_size = 511 - min + 1;
|
||||
} else {
|
||||
min = 600;
|
||||
range_size = 1023 - min + 1;
|
||||
}
|
||||
} else {
|
||||
min = 1024;
|
||||
range_size = 65535 - 1024 + 1;
|
||||
}
|
||||
} else {
|
||||
min = ntohs(range->min.tcp.port);
|
||||
range_size = ntohs(range->max.tcp.port) - min + 1;
|
||||
}
|
||||
|
||||
if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
|
||||
port = net_random();
|
||||
|
||||
for (i = 0; i < range_size; i++, port++) {
|
||||
*portptr = htons(min + port % range_size);
|
||||
if (!nf_nat_used_tuple(tuple, ct))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
|
||||
&tcp_port_rover);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
tcp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
@@ -107,7 +50,7 @@ tcp_manip_pkt(struct sk_buff *skb,
|
||||
hdrsize = sizeof(struct tcphdr);
|
||||
|
||||
if (!skb_make_writable(skb, hdroff + hdrsize))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
hdr = (struct tcphdr *)(skb->data + hdroff);
|
||||
@@ -130,22 +73,21 @@ tcp_manip_pkt(struct sk_buff *skb,
|
||||
*portptr = newport;
|
||||
|
||||
if (hdrsize < sizeof(*hdr))
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
|
||||
inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, 0);
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct nf_nat_protocol nf_nat_protocol_tcp = {
|
||||
.name = "TCP",
|
||||
.protonum = IPPROTO_TCP,
|
||||
.me = THIS_MODULE,
|
||||
.manip_pkt = tcp_manip_pkt,
|
||||
.in_range = tcp_in_range,
|
||||
.in_range = nf_nat_proto_in_range,
|
||||
.unique_tuple = tcp_unique_tuple,
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
.range_to_nlattr = nf_nat_port_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_port_nlattr_to_range,
|
||||
.range_to_nlattr = nf_nat_proto_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_proto_nlattr_to_range,
|
||||
#endif
|
||||
};
|
||||
|
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
@@ -18,74 +17,19 @@
|
||||
#include <net/netfilter/nf_nat_rule.h>
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
|
||||
static int
|
||||
udp_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
const union nf_conntrack_man_proto *max)
|
||||
{
|
||||
__be16 port;
|
||||
static u_int16_t udp_port_rover;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
port = tuple->src.u.udp.port;
|
||||
else
|
||||
port = tuple->dst.u.udp.port;
|
||||
|
||||
return ntohs(port) >= ntohs(min->udp.port) &&
|
||||
ntohs(port) <= ntohs(max->udp.port);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
udp_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct)
|
||||
{
|
||||
static u_int16_t port;
|
||||
__be16 *portptr;
|
||||
unsigned int range_size, min, i;
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC)
|
||||
portptr = &tuple->src.u.udp.port;
|
||||
else
|
||||
portptr = &tuple->dst.u.udp.port;
|
||||
|
||||
/* If no range specified... */
|
||||
if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
|
||||
/* If it's dst rewrite, can't change port */
|
||||
if (maniptype == IP_NAT_MANIP_DST)
|
||||
return 0;
|
||||
|
||||
if (ntohs(*portptr) < 1024) {
|
||||
/* Loose convention: >> 512 is credential passing */
|
||||
if (ntohs(*portptr)<512) {
|
||||
min = 1;
|
||||
range_size = 511 - min + 1;
|
||||
} else {
|
||||
min = 600;
|
||||
range_size = 1023 - min + 1;
|
||||
}
|
||||
} else {
|
||||
min = 1024;
|
||||
range_size = 65535 - 1024 + 1;
|
||||
}
|
||||
} else {
|
||||
min = ntohs(range->min.udp.port);
|
||||
range_size = ntohs(range->max.udp.port) - min + 1;
|
||||
}
|
||||
|
||||
if (range->flags & IP_NAT_RANGE_PROTO_RANDOM)
|
||||
port = net_random();
|
||||
|
||||
for (i = 0; i < range_size; i++, port++) {
|
||||
*portptr = htons(min + port % range_size);
|
||||
if (!nf_nat_used_tuple(tuple, ct))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
|
||||
&udp_port_rover);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
udp_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
@@ -98,7 +42,7 @@ udp_manip_pkt(struct sk_buff *skb,
|
||||
__be16 *portptr, newport;
|
||||
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
hdr = (struct udphdr *)(skb->data + hdroff);
|
||||
@@ -124,18 +68,17 @@ udp_manip_pkt(struct sk_buff *skb,
|
||||
hdr->check = CSUM_MANGLED_0;
|
||||
}
|
||||
*portptr = newport;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct nf_nat_protocol nf_nat_protocol_udp = {
|
||||
.name = "UDP",
|
||||
.protonum = IPPROTO_UDP,
|
||||
.me = THIS_MODULE,
|
||||
.manip_pkt = udp_manip_pkt,
|
||||
.in_range = udp_in_range,
|
||||
.in_range = nf_nat_proto_in_range,
|
||||
.unique_tuple = udp_unique_tuple,
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
.range_to_nlattr = nf_nat_port_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_port_nlattr_to_range,
|
||||
.range_to_nlattr = nf_nat_proto_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_proto_nlattr_to_range,
|
||||
#endif
|
||||
};
|
||||
|
99
net/ipv4/netfilter/nf_nat_proto_udplite.c
Normal file
99
net/ipv4/netfilter/nf_nat_proto_udplite.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/* (C) 1999-2001 Paul `Rusty' Russell
|
||||
* (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
|
||||
* (C) 2008 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/types.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
|
||||
#include <linux/netfilter.h>
|
||||
#include <net/netfilter/nf_nat.h>
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
|
||||
static u_int16_t udplite_port_rover;
|
||||
|
||||
static bool
|
||||
udplite_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct)
|
||||
{
|
||||
return nf_nat_proto_unique_tuple(tuple, range, maniptype, ct,
|
||||
&udplite_port_rover);
|
||||
}
|
||||
|
||||
static bool
|
||||
udplite_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
struct udphdr *hdr;
|
||||
unsigned int hdroff = iphdroff + iph->ihl*4;
|
||||
__be32 oldip, newip;
|
||||
__be16 *portptr, newport;
|
||||
|
||||
if (!skb_make_writable(skb, hdroff + sizeof(*hdr)))
|
||||
return false;
|
||||
|
||||
iph = (struct iphdr *)(skb->data + iphdroff);
|
||||
hdr = (struct udphdr *)(skb->data + hdroff);
|
||||
|
||||
if (maniptype == IP_NAT_MANIP_SRC) {
|
||||
/* Get rid of src ip and src pt */
|
||||
oldip = iph->saddr;
|
||||
newip = tuple->src.u3.ip;
|
||||
newport = tuple->src.u.udp.port;
|
||||
portptr = &hdr->source;
|
||||
} else {
|
||||
/* Get rid of dst ip and dst pt */
|
||||
oldip = iph->daddr;
|
||||
newip = tuple->dst.u3.ip;
|
||||
newport = tuple->dst.u.udp.port;
|
||||
portptr = &hdr->dest;
|
||||
}
|
||||
|
||||
inet_proto_csum_replace4(&hdr->check, skb, oldip, newip, 1);
|
||||
inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport, 0);
|
||||
if (!hdr->check)
|
||||
hdr->check = CSUM_MANGLED_0;
|
||||
|
||||
*portptr = newport;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct nf_nat_protocol nf_nat_protocol_udplite = {
|
||||
.protonum = IPPROTO_UDPLITE,
|
||||
.me = THIS_MODULE,
|
||||
.manip_pkt = udplite_manip_pkt,
|
||||
.in_range = nf_nat_proto_in_range,
|
||||
.unique_tuple = udplite_unique_tuple,
|
||||
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
|
||||
.range_to_nlattr = nf_nat_proto_range_to_nlattr,
|
||||
.nlattr_to_range = nf_nat_proto_nlattr_to_range,
|
||||
#endif
|
||||
};
|
||||
|
||||
static int __init nf_nat_proto_udplite_init(void)
|
||||
{
|
||||
return nf_nat_protocol_register(&nf_nat_protocol_udplite);
|
||||
}
|
||||
|
||||
static void __exit nf_nat_proto_udplite_fini(void)
|
||||
{
|
||||
nf_nat_protocol_unregister(&nf_nat_protocol_udplite);
|
||||
}
|
||||
|
||||
module_init(nf_nat_proto_udplite_init);
|
||||
module_exit(nf_nat_proto_udplite_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("UDP-Lite NAT protocol helper");
|
||||
MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
|
@@ -18,35 +18,34 @@
|
||||
#include <net/netfilter/nf_nat_rule.h>
|
||||
#include <net/netfilter/nf_nat_protocol.h>
|
||||
|
||||
static int unknown_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type manip_type,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
const union nf_conntrack_man_proto *max)
|
||||
static bool unknown_in_range(const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type manip_type,
|
||||
const union nf_conntrack_man_proto *min,
|
||||
const union nf_conntrack_man_proto *max)
|
||||
{
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int unknown_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct)
|
||||
static bool unknown_unique_tuple(struct nf_conntrack_tuple *tuple,
|
||||
const struct nf_nat_range *range,
|
||||
enum nf_nat_manip_type maniptype,
|
||||
const struct nf_conn *ct)
|
||||
{
|
||||
/* Sorry: we can't help you; if it's not unique, we can't frob
|
||||
anything. */
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
unknown_manip_pkt(struct sk_buff *skb,
|
||||
unsigned int iphdroff,
|
||||
const struct nf_conntrack_tuple *tuple,
|
||||
enum nf_nat_manip_type maniptype)
|
||||
{
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
const struct nf_nat_protocol nf_nat_unknown_protocol = {
|
||||
.name = "unknown",
|
||||
/* .me isn't set: getting a ref to this cannot fail. */
|
||||
.manip_pkt = unknown_manip_pkt,
|
||||
.in_range = unknown_in_range,
|
||||
|
@@ -61,7 +61,7 @@ static struct
|
||||
static struct xt_table __nat_table = {
|
||||
.name = "nat",
|
||||
.valid_hooks = NAT_VALID_HOOKS,
|
||||
.lock = RW_LOCK_UNLOCKED,
|
||||
.lock = __RW_LOCK_UNLOCKED(__nat_table.lock),
|
||||
.me = THIS_MODULE,
|
||||
.af = AF_INET,
|
||||
};
|
||||
@@ -143,7 +143,7 @@ static bool ipt_snat_checkentry(const char *tablename,
|
||||
void *targinfo,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct nf_nat_multi_range_compat *mr = targinfo;
|
||||
const struct nf_nat_multi_range_compat *mr = targinfo;
|
||||
|
||||
/* Must be a valid range */
|
||||
if (mr->rangesize != 1) {
|
||||
@@ -159,7 +159,7 @@ static bool ipt_dnat_checkentry(const char *tablename,
|
||||
void *targinfo,
|
||||
unsigned int hook_mask)
|
||||
{
|
||||
struct nf_nat_multi_range_compat *mr = targinfo;
|
||||
const struct nf_nat_multi_range_compat *mr = targinfo;
|
||||
|
||||
/* Must be a valid range */
|
||||
if (mr->rangesize != 1) {
|
||||
@@ -188,25 +188,6 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum)
|
||||
return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
|
||||
}
|
||||
|
||||
unsigned int
|
||||
alloc_null_binding_confirmed(struct nf_conn *ct, unsigned int hooknum)
|
||||
{
|
||||
__be32 ip
|
||||
= (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
|
||||
? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip
|
||||
: ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
|
||||
__be16 all
|
||||
= (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
|
||||
? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
|
||||
: ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
|
||||
struct nf_nat_range range
|
||||
= { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
|
||||
|
||||
pr_debug("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
|
||||
ct, NIPQUAD(ip));
|
||||
return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
|
||||
}
|
||||
|
||||
int nf_nat_rule_find(struct sk_buff *skb,
|
||||
unsigned int hooknum,
|
||||
const struct net_device *in,
|
||||
|
@@ -220,7 +220,7 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
|
||||
if (ch < 0x80)
|
||||
*len = ch;
|
||||
else {
|
||||
cnt = (unsigned char) (ch & 0x7F);
|
||||
cnt = ch & 0x7F;
|
||||
*len = 0;
|
||||
|
||||
while (cnt > 0) {
|
||||
@@ -618,8 +618,7 @@ struct snmp_cnv
|
||||
int syntax;
|
||||
};
|
||||
|
||||
static struct snmp_cnv snmp_conv [] =
|
||||
{
|
||||
static const struct snmp_cnv snmp_conv[] = {
|
||||
{ASN1_UNI, ASN1_NUL, SNMP_NULL},
|
||||
{ASN1_UNI, ASN1_INT, SNMP_INTEGER},
|
||||
{ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
|
||||
@@ -644,7 +643,7 @@ static unsigned char snmp_tag_cls2syntax(unsigned int tag,
|
||||
unsigned int cls,
|
||||
unsigned short *syntax)
|
||||
{
|
||||
struct snmp_cnv *cnv;
|
||||
const struct snmp_cnv *cnv;
|
||||
|
||||
cnv = snmp_conv;
|
||||
|
||||
@@ -904,7 +903,7 @@ static inline void mangle_address(unsigned char *begin,
|
||||
u_int32_t old;
|
||||
|
||||
if (debug)
|
||||
memcpy(&old, (unsigned char *)addr, sizeof(old));
|
||||
memcpy(&old, addr, sizeof(old));
|
||||
|
||||
*addr = map->to;
|
||||
|
||||
@@ -999,7 +998,7 @@ err_id_free:
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
static void hex_dump(unsigned char *buf, size_t len)
|
||||
static void hex_dump(const unsigned char *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -1080,7 +1079,7 @@ static int snmp_parse_mangle(unsigned char *msg,
|
||||
if (cls != ASN1_CTX || con != ASN1_CON)
|
||||
return 0;
|
||||
if (debug > 1) {
|
||||
unsigned char *pdus[] = {
|
||||
static const unsigned char *const pdus[] = {
|
||||
[SNMP_PDU_GET] = "get",
|
||||
[SNMP_PDU_NEXT] = "get-next",
|
||||
[SNMP_PDU_RESPONSE] = "response",
|
||||
@@ -1232,8 +1231,8 @@ static int help(struct sk_buff *skb, unsigned int protoff,
|
||||
{
|
||||
int dir = CTINFO2DIR(ctinfo);
|
||||
unsigned int ret;
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
const struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
|
||||
|
||||
/* SNMP replies and originating SNMP traps get mangled */
|
||||
if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
|
||||
|
@@ -30,8 +30,8 @@
|
||||
#ifdef CONFIG_XFRM
|
||||
static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
|
||||
{
|
||||
struct nf_conn *ct;
|
||||
struct nf_conntrack_tuple *t;
|
||||
const struct nf_conn *ct;
|
||||
const struct nf_conntrack_tuple *t;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
enum ip_conntrack_dir dir;
|
||||
unsigned long statusbit;
|
||||
@@ -50,7 +50,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
|
||||
if (ct->status & statusbit) {
|
||||
fl->fl4_dst = t->dst.u3.ip;
|
||||
if (t->dst.protonum == IPPROTO_TCP ||
|
||||
t->dst.protonum == IPPROTO_UDP)
|
||||
t->dst.protonum == IPPROTO_UDP ||
|
||||
t->dst.protonum == IPPROTO_UDPLITE ||
|
||||
t->dst.protonum == IPPROTO_DCCP ||
|
||||
t->dst.protonum == IPPROTO_SCTP)
|
||||
fl->fl_ip_dport = t->dst.u.tcp.port;
|
||||
}
|
||||
|
||||
@@ -59,7 +62,10 @@ static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
|
||||
if (ct->status & statusbit) {
|
||||
fl->fl4_src = t->src.u3.ip;
|
||||
if (t->dst.protonum == IPPROTO_TCP ||
|
||||
t->dst.protonum == IPPROTO_UDP)
|
||||
t->dst.protonum == IPPROTO_UDP ||
|
||||
t->dst.protonum == IPPROTO_UDPLITE ||
|
||||
t->dst.protonum == IPPROTO_DCCP ||
|
||||
t->dst.protonum == IPPROTO_SCTP)
|
||||
fl->fl_ip_sport = t->src.u.tcp.port;
|
||||
}
|
||||
}
|
||||
@@ -87,21 +93,8 @@ nf_nat_fn(unsigned int hooknum,
|
||||
have dropped it. Hence it's the user's responsibilty to
|
||||
packet filter it out, or implement conntrack/NAT for that
|
||||
protocol. 8) --RR */
|
||||
if (!ct) {
|
||||
/* Exception: ICMP redirect to new connection (not in
|
||||
hash table yet). We must not let this through, in
|
||||
case we're doing NAT to the same network. */
|
||||
if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
|
||||
struct icmphdr _hdr, *hp;
|
||||
|
||||
hp = skb_header_pointer(skb, ip_hdrlen(skb),
|
||||
sizeof(_hdr), &_hdr);
|
||||
if (hp != NULL &&
|
||||
hp->type == ICMP_REDIRECT)
|
||||
return NF_DROP;
|
||||
}
|
||||
if (!ct)
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* Don't try to NAT if this packet is not conntracked */
|
||||
if (ct == &nf_conntrack_untracked)
|
||||
@@ -109,6 +102,9 @@ nf_nat_fn(unsigned int hooknum,
|
||||
|
||||
nat = nfct_nat(ct);
|
||||
if (!nat) {
|
||||
/* NAT module was loaded late. */
|
||||
if (nf_ct_is_confirmed(ct))
|
||||
return NF_ACCEPT;
|
||||
nat = nf_ct_ext_add(ct, NF_CT_EXT_NAT, GFP_ATOMIC);
|
||||
if (nat == NULL) {
|
||||
pr_debug("failed to add NAT extension\n");
|
||||
@@ -134,10 +130,7 @@ nf_nat_fn(unsigned int hooknum,
|
||||
if (!nf_nat_initialized(ct, maniptype)) {
|
||||
unsigned int ret;
|
||||
|
||||
if (unlikely(nf_ct_is_confirmed(ct)))
|
||||
/* NAT module was loaded late */
|
||||
ret = alloc_null_binding_confirmed(ct, hooknum);
|
||||
else if (hooknum == NF_INET_LOCAL_IN)
|
||||
if (hooknum == NF_INET_LOCAL_IN)
|
||||
/* LOCAL_IN hook doesn't have a chain! */
|
||||
ret = alloc_null_binding(ct, hooknum);
|
||||
else
|
||||
@@ -189,7 +182,7 @@ nf_nat_out(unsigned int hooknum,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
#ifdef CONFIG_XFRM
|
||||
struct nf_conn *ct;
|
||||
const struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
#endif
|
||||
unsigned int ret;
|
||||
@@ -223,7 +216,7 @@ nf_nat_local_fn(unsigned int hooknum,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct nf_conn *ct;
|
||||
const struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
unsigned int ret;
|
||||
|
||||
@@ -252,25 +245,6 @@ nf_nat_local_fn(unsigned int hooknum,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
nf_nat_adjust(unsigned int hooknum,
|
||||
struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
struct nf_conn *ct;
|
||||
enum ip_conntrack_info ctinfo;
|
||||
|
||||
ct = nf_ct_get(skb, &ctinfo);
|
||||
if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
|
||||
pr_debug("nf_nat_standalone: adjusting sequence number\n");
|
||||
if (!nf_nat_seq_adjust(skb, ct, ctinfo))
|
||||
return NF_DROP;
|
||||
}
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
|
||||
/* We must be after connection tracking and before packet filtering. */
|
||||
|
||||
static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
|
||||
@@ -290,14 +264,6 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_NAT_SRC,
|
||||
},
|
||||
/* After conntrack, adjust sequence number */
|
||||
{
|
||||
.hook = nf_nat_adjust,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_POST_ROUTING,
|
||||
.priority = NF_IP_PRI_NAT_SEQ_ADJUST,
|
||||
},
|
||||
/* Before packet filtering, change destination */
|
||||
{
|
||||
.hook = nf_nat_local_fn,
|
||||
@@ -314,14 +280,6 @@ static struct nf_hook_ops nf_nat_ops[] __read_mostly = {
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_NAT_SRC,
|
||||
},
|
||||
/* After conntrack, adjust sequence number */
|
||||
{
|
||||
.hook = nf_nat_adjust,
|
||||
.owner = THIS_MODULE,
|
||||
.pf = PF_INET,
|
||||
.hooknum = NF_INET_LOCAL_IN,
|
||||
.priority = NF_IP_PRI_NAT_SEQ_ADJUST,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init nf_nat_standalone_init(void)
|
||||
|
Reference in New Issue
Block a user