Compare commits

...

7 Commits
v2.9 ... v2.10

Author SHA1 Message Date
Jan Engelhardt
5038e160f8 Xtables-addons 2.10 2015-11-20 23:30:33 +01:00
Jan Engelhardt
a6289ec3ff build: silence compiler warning in xt_quota2
xt_quota2.c:67:6: warning: unused variable "ret" [-Wunused-variable]
2015-11-20 23:17:40 +01:00
Jan Engelhardt
01e7128a80 build: support for Linux 4.4 2015-11-20 23:17:39 +01:00
Jan Engelhardt
1dc2a1c2de xt_ACCOUNT: remove redundant braces
For single-line statements, the {} are not strictly needed.
2015-11-09 22:33:49 +01:00
Jan Engelhardt
60b6b1dbef xt_ACCOUNT: indent reduction
Invert early terminating conditions so the rest of the block can be
de-indented.
2015-11-09 22:33:49 +01:00
Jan Engelhardt
fcb19403bc xt_ACCOUNT: call free_pages(x,2) (doc)
Below is the patch with the *rest* of the free_page(X) calls changed
to free_pages(X, 2). xt_ACCOUNT should always allocate memory in page
pairs. And always *free* memory in page pairs.

References: http://www.spinics.net/lists/netfilter-devel/msg39025.html
2015-11-09 22:33:47 +01:00
Neil P. Murphy
f89f10bbe9 xt_ACCOUNT: call free_pages(x,2)
Below is the patch with the *rest* of the free_page(X) calls changed
to free_pages(X, 2). xt_ACCOUNT should always allocate memory in page
pairs. And always *free* memory in page pairs.

References: http://www.spinics.net/lists/netfilter-devel/msg39025.html
2015-11-09 22:25:16 +01:00
9 changed files with 112 additions and 87 deletions

View File

@@ -1,4 +1,4 @@
AC_INIT([xtables-addons], [2.9]) AC_INIT([xtables-addons], [2.10])
AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h]) AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View File

@@ -3,6 +3,14 @@ HEAD
==== ====
v2.10 (2015-11-20)
==================
Enhancements:
- Support for Linux 4.4
Fixes:
- xt_ACCOUNT: call free_page with the right amount of pages
v2.9 (2015-10-12) v2.9 (2015-10-12)
================= =================
Enhancements: Enhancements:

View File

@@ -115,10 +115,8 @@ static void *ipt_acc_zalloc_page(void)
// Don't use get_zeroed_page until it's fixed in the kernel. // Don't use get_zeroed_page until it's fixed in the kernel.
// get_zeroed_page(GFP_ATOMIC) // get_zeroed_page(GFP_ATOMIC)
void *mem = (void *)__get_free_pages(GFP_ATOMIC, 2); void *mem = (void *)__get_free_pages(GFP_ATOMIC, 2);
if (mem) { if (mem != NULL)
memset(mem, 0, 2 *PAGE_SIZE); memset(mem, 0, 2 *PAGE_SIZE);
}
return mem; return mem;
} }
@@ -139,11 +137,9 @@ static void ipt_acc_data_free(void *data, uint8_t depth)
if (depth == 1) { if (depth == 1) {
struct ipt_acc_mask_16 *mask_16 = data; struct ipt_acc_mask_16 *mask_16 = data;
unsigned int b; unsigned int b;
for (b = 0; b <= 255; b++) { for (b = 0; b <= 255; ++b)
if (mask_16->mask_24[b]) { if (mask_16->mask_24[b])
free_page((unsigned long)mask_16->mask_24[b]); free_pages((unsigned long)mask_16->mask_24[b], 2);
}
}
free_pages((unsigned long)data, 2); free_pages((unsigned long)data, 2);
return; return;
} }
@@ -156,12 +152,10 @@ static void ipt_acc_data_free(void *data, uint8_t depth)
struct ipt_acc_mask_16 *mask_16 = struct ipt_acc_mask_16 *mask_16 =
((struct ipt_acc_mask_8 *)data)->mask_16[a]; ((struct ipt_acc_mask_8 *)data)->mask_16[a];
for (b = 0; b <= 255; b++) { for (b = 0; b <= 255; ++b)
if (mask_16->mask_24[b]) { if (mask_16->mask_24[b])
free_page((unsigned long)mask_16->mask_24[b]); free_pages((unsigned long)mask_16->mask_24[b], 2);
} free_pages((unsigned long)mask_16, 2);
}
free_page((unsigned long)mask_16);
} }
} }
free_pages((unsigned long)data, 2); free_pages((unsigned long)data, 2);
@@ -631,18 +625,18 @@ static int ipt_acc_handle_prepare_read(char *tablename,
unsigned int b; unsigned int b;
for (b = 0; b <= 255; b++) { for (b = 0; b <= 255; b++) {
if (src_16->mask_24[b]) { if (src_16->mask_24[b] == NULL)
if ((network_16->mask_24[b] = continue;
ipt_acc_zalloc_page()) == NULL) { if ((network_16->mask_24[b] =
printk("ACCOUNT: out of memory during copy of 16 bit " ipt_acc_zalloc_page()) == NULL) {
"network in ipt_acc_handle_prepare_read()\n"); printk("ACCOUNT: out of memory during copy of 16 bit "
ipt_acc_data_free(dest->data, depth); "network in ipt_acc_handle_prepare_read()\n");
return -1; ipt_acc_data_free(dest->data, depth);
} return -1;
memcpy(network_16->mask_24[b], src_16->mask_24[b],
sizeof(struct ipt_acc_mask_24));
} }
memcpy(network_16->mask_24[b], src_16->mask_24[b],
sizeof(struct ipt_acc_mask_24));
} }
} else if (depth == 2) { } else if (depth == 2) {
struct ipt_acc_mask_8 *src_8 = struct ipt_acc_mask_8 *src_8 =
@@ -652,35 +646,35 @@ static int ipt_acc_handle_prepare_read(char *tablename,
unsigned int a, b; unsigned int a, b;
for (a = 0; a <= 255; a++) { for (a = 0; a <= 255; a++) {
if (src_8->mask_16[a]) { if (src_8->mask_16[a] == NULL)
if ((network_8->mask_16[a] = continue;
if ((network_8->mask_16[a] =
ipt_acc_zalloc_page()) == NULL) {
printk("ACCOUNT: out of memory during copy of 24 bit network"
" in ipt_acc_handle_prepare_read()\n");
ipt_acc_data_free(dest->data, depth);
return -1;
}
memcpy(network_8->mask_16[a], src_8->mask_16[a],
sizeof(struct ipt_acc_mask_16));
src_16 = src_8->mask_16[a];
network_16 = network_8->mask_16[a];
for (b = 0; b <= 255; b++) {
if (src_16->mask_24[b] == NULL)
continue;
if ((network_16->mask_24[b] =
ipt_acc_zalloc_page()) == NULL) { ipt_acc_zalloc_page()) == NULL) {
printk("ACCOUNT: out of memory during copy of 24 bit network" printk("ACCOUNT: out of memory during copy of 16 bit"
" in ipt_acc_handle_prepare_read()\n"); " network in ipt_acc_handle_prepare_read()\n");
ipt_acc_data_free(dest->data, depth); ipt_acc_data_free(dest->data, depth);
return -1; return -1;
} }
memcpy(network_8->mask_16[a], src_8->mask_16[a], memcpy(network_16->mask_24[b], src_16->mask_24[b],
sizeof(struct ipt_acc_mask_16)); sizeof(struct ipt_acc_mask_24));
src_16 = src_8->mask_16[a];
network_16 = network_8->mask_16[a];
for (b = 0; b <= 255; b++) {
if (src_16->mask_24[b]) {
if ((network_16->mask_24[b] =
ipt_acc_zalloc_page()) == NULL) {
printk("ACCOUNT: out of memory during copy of 16 bit"
" network in ipt_acc_handle_prepare_read()\n");
ipt_acc_data_free(dest->data, depth);
return -1;
}
memcpy(network_16->mask_24[b], src_16->mask_24[b],
sizeof(struct ipt_acc_mask_24));
}
}
} }
} }
} }
@@ -742,25 +736,26 @@ static int ipt_acc_handle_copy_data(void *to_user, unsigned long *to_user_pos,
unsigned int i; unsigned int i;
for (i = 0; i <= 255; i++) { for (i = 0; i <= 255; i++) {
if (data->ip[i].src_packets || data->ip[i].dst_packets) { if (data->ip[i].src_packets == 0 &&
handle_ip.ip = net_ip | net_OR_mask | i; data->ip[i].dst_packets == 0)
continue;
handle_ip.src_packets = data->ip[i].src_packets; handle_ip.ip = net_ip | net_OR_mask | i;
handle_ip.src_bytes = data->ip[i].src_bytes; handle_ip.src_packets = data->ip[i].src_packets;
handle_ip.dst_packets = data->ip[i].dst_packets; handle_ip.src_bytes = data->ip[i].src_bytes;
handle_ip.dst_bytes = data->ip[i].dst_bytes; handle_ip.dst_packets = data->ip[i].dst_packets;
handle_ip.dst_bytes = data->ip[i].dst_bytes;
/* Temporary buffer full? Flush to userspace */ /* Temporary buffer full? Flush to userspace */
if (*tmpbuf_pos + handle_ip_size >= PAGE_SIZE) { if (*tmpbuf_pos + handle_ip_size >= PAGE_SIZE) {
if (copy_to_user(to_user + *to_user_pos, ipt_acc_tmpbuf, if (copy_to_user(to_user + *to_user_pos, ipt_acc_tmpbuf,
*tmpbuf_pos)) *tmpbuf_pos))
return -EFAULT; return -EFAULT;
*to_user_pos = *to_user_pos + *tmpbuf_pos; *to_user_pos = *to_user_pos + *tmpbuf_pos;
*tmpbuf_pos = 0; *tmpbuf_pos = 0;
}
memcpy(ipt_acc_tmpbuf + *tmpbuf_pos, &handle_ip, handle_ip_size);
*tmpbuf_pos += handle_ip_size;
} }
memcpy(ipt_acc_tmpbuf + *tmpbuf_pos, &handle_ip, handle_ip_size);
*tmpbuf_pos += handle_ip_size;
} }
return 0; return 0;

View File

@@ -73,4 +73,20 @@ static inline void proc_remove(struct proc_dir_entry *de)
} }
#endif #endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 0)
# define ip6_local_out(xnet, xsk, xskb) ip6_local_out(xskb)
# define ip6_route_me_harder(xnet, xskb) ip6_route_me_harder(xskb)
# define ip_local_out(xnet, xsk, xskb) ip_local_out(xskb)
# define ip_route_me_harder(xnet, xskb, xaddrtype) ip_route_me_harder((xskb), (xaddrtype))
#endif
static inline struct net *par_net(const struct xt_action_param *par)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
return par->net;
#else
return dev_net((par->in != NULL) ? par->in : par->out);
#endif
}
#endif /* _XTABLES_COMPAT_H */ #endif /* _XTABLES_COMPAT_H */

View File

@@ -25,7 +25,8 @@
#include "compat_xtables.h" #include "compat_xtables.h"
#define PFX KBUILD_MODNAME ": " #define PFX KBUILD_MODNAME ": "
static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook) static void delude_send_reset(struct net *net, struct sk_buff *oldskb,
unsigned int hook)
{ {
struct tcphdr _otcph, *tcph; struct tcphdr _otcph, *tcph;
const struct tcphdr *oth; const struct tcphdr *oth;
@@ -121,7 +122,7 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
/* ip_route_me_harder expects skb->dst to be set */ /* ip_route_me_harder expects skb->dst to be set */
skb_dst_set(nskb, dst_clone(skb_dst(oldskb))); skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
if (ip_route_me_harder(nskb, addr_type)) if (ip_route_me_harder(net, nskb, addr_type))
goto free_nskb; goto free_nskb;
else else
niph = ip_hdr(nskb); niph = ip_hdr(nskb);
@@ -135,7 +136,7 @@ static void delude_send_reset(struct sk_buff *oldskb, unsigned int hook)
nf_ct_attach(nskb, oldskb); nf_ct_attach(nskb, oldskb);
ip_local_out(nskb); ip_local_out(net, nskb->sk, nskb);
return; return;
free_nskb: free_nskb:
@@ -150,7 +151,7 @@ delude_tg(struct sk_buff *skb, const struct xt_action_param *par)
* a problem, as that is supported since Linux 2.6.35. But since we do not * a problem, as that is supported since Linux 2.6.35. But since we do not
* actually want to have a connection open, we are still going to drop it. * actually want to have a connection open, we are still going to drop it.
*/ */
delude_send_reset(skb, par->hooknum); delude_send_reset(par_net(par), skb, par->hooknum);
return NF_DROP; return NF_DROP;
} }

View File

@@ -112,7 +112,7 @@ echo_tg6(struct sk_buff *oldskb, const struct xt_action_param *par)
goto free_nskb; goto free_nskb;
nf_ct_attach(newskb, oldskb); nf_ct_attach(newskb, oldskb);
ip6_local_out(newskb); ip6_local_out(par_net(par), newskb->sk, newskb);
return NF_DROP; return NF_DROP;
free_nskb: free_nskb:
@@ -190,7 +190,7 @@ echo_tg4(struct sk_buff *oldskb, const struct xt_action_param *par)
/* ip_route_me_harder expects the skb's dst to be set */ /* ip_route_me_harder expects the skb's dst to be set */
skb_dst_set(newskb, dst_clone(skb_dst(oldskb))); skb_dst_set(newskb, dst_clone(skb_dst(oldskb)));
if (ip_route_me_harder(newskb, RTN_UNSPEC) != 0) if (ip_route_me_harder(par_net(par), newskb, RTN_UNSPEC) != 0)
goto free_nskb; goto free_nskb;
newip->ttl = ip4_dst_hoplimit(skb_dst(newskb)); newip->ttl = ip4_dst_hoplimit(skb_dst(newskb));
@@ -201,7 +201,7 @@ echo_tg4(struct sk_buff *oldskb, const struct xt_action_param *par)
goto free_nskb; goto free_nskb;
nf_ct_attach(newskb, oldskb); nf_ct_attach(newskb, oldskb);
ip_local_out(newskb); ip_local_out(par_net(par), newskb->sk, newskb);
return NF_DROP; return NF_DROP;
free_nskb: free_nskb:

View File

@@ -170,8 +170,8 @@ static bool tarpit_generic(struct tcphdr *tcph, const struct tcphdr *oth,
return true; return true;
} }
static void tarpit_tcp4(struct sk_buff *oldskb, unsigned int hook, static void tarpit_tcp4(struct net *net, struct sk_buff *oldskb,
unsigned int mode) unsigned int hook, unsigned int mode)
{ {
struct tcphdr _otcph, *tcph; struct tcphdr _otcph, *tcph;
const struct tcphdr *oth; const struct tcphdr *oth;
@@ -261,7 +261,7 @@ static void tarpit_tcp4(struct sk_buff *oldskb, unsigned int hook,
#endif #endif
addr_type = RTN_LOCAL; addr_type = RTN_LOCAL;
if (ip_route_me_harder(nskb, addr_type)) if (ip_route_me_harder(net, nskb, addr_type))
goto free_nskb; goto free_nskb;
else else
niph = ip_hdr(nskb); niph = ip_hdr(nskb);
@@ -284,8 +284,11 @@ static void tarpit_tcp4(struct sk_buff *oldskb, unsigned int hook,
nf_ct_attach(nskb, oldskb); nf_ct_attach(nskb, oldskb);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, NULL, nskb, NULL, NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, net, nskb->sk, nskb, NULL,
skb_dst(nskb)->dev, dst_output);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb->sk, nskb, NULL,
skb_dst(nskb)->dev, dst_output_sk); skb_dst(nskb)->dev, dst_output_sk);
#else #else
NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL, NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_OUT, nskb, NULL,
@@ -298,8 +301,8 @@ static void tarpit_tcp4(struct sk_buff *oldskb, unsigned int hook,
} }
#ifdef WITH_IPV6 #ifdef WITH_IPV6
static void tarpit_tcp6(struct sk_buff *oldskb, unsigned int hook, static void tarpit_tcp6(struct net *net, struct sk_buff *oldskb,
unsigned int mode) unsigned int hook, unsigned int mode)
{ {
struct sk_buff *nskb; struct sk_buff *nskb;
struct tcphdr *tcph, oth; struct tcphdr *tcph, oth;
@@ -397,15 +400,18 @@ static void tarpit_tcp6(struct sk_buff *oldskb, unsigned int hook,
IPPROTO_TCP, IPPROTO_TCP,
csum_partial(tcph, sizeof(struct tcphdr), 0)); csum_partial(tcph, sizeof(struct tcphdr), 0));
if (ip6_route_me_harder(nskb)) if (ip6_route_me_harder(net, nskb))
goto free_nskb; goto free_nskb;
nskb->ip_summed = CHECKSUM_NONE; nskb->ip_summed = CHECKSUM_NONE;
nf_ct_attach(nskb, oldskb); nf_ct_attach(nskb, oldskb);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, NULL, nskb, NULL, NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, net, nskb->sk, nskb, NULL,
skb_dst(nskb)->dev, dst_output);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, nskb->sk, nskb, NULL,
skb_dst(nskb)->dev, dst_output_sk); skb_dst(nskb)->dev, dst_output_sk);
#else #else
NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, nskb, NULL, NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, nskb, NULL,
@@ -449,7 +455,7 @@ tarpit_tg4(struct sk_buff *skb, const struct xt_action_param *par)
if (iph->frag_off & htons(IP_OFFSET)) if (iph->frag_off & htons(IP_OFFSET))
return NF_DROP; return NF_DROP;
tarpit_tcp4(skb, par->hooknum, info->variant); tarpit_tcp4(par_net(par), skb, par->hooknum, info->variant);
return NF_DROP; return NF_DROP;
} }
@@ -491,7 +497,7 @@ tarpit_tg6(struct sk_buff *skb, const struct xt_action_param *par)
return NF_DROP; return NF_DROP;
} }
tarpit_tcp6(skb, par->hooknum, info->variant); tarpit_tcp6(par_net(par), skb, par->hooknum, info->variant);
return NF_DROP; return NF_DROP;
} }
#endif #endif

View File

@@ -64,7 +64,6 @@ module_param_named(gid, quota_list_gid, uint, S_IRUGO | S_IWUSR);
static int quota_proc_show(struct seq_file *m, void *data) static int quota_proc_show(struct seq_file *m, void *data)
{ {
struct xt_quota_counter *e = m->private; struct xt_quota_counter *e = m->private;
int ret;
spin_lock_bh(&e->lock); spin_lock_bh(&e->lock);
seq_printf(m, "%llu\n", e->quota); seq_printf(m, "%llu\n", e->quota);

View File

@@ -1,4 +1,4 @@
.TH xtables-addons 8 "" "" "v2.9 (2015-10-12)" .TH xtables-addons 8 "" "" "v2.10 (2015-11-20)"
.SH Name .SH Name
Xtables-addons \(em additional extensions for iptables, ip6tables, etc. Xtables-addons \(em additional extensions for iptables, ip6tables, etc.
.SH Targets .SH Targets