summaryrefslogtreecommitdiffstats
path: root/ip6t_MAP66.c
diff options
context:
space:
mode:
Diffstat (limited to 'ip6t_MAP66.c')
-rw-r--r--ip6t_MAP66.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/ip6t_MAP66.c b/ip6t_MAP66.c
index 6446927..ca0e559 100644
--- a/ip6t_MAP66.c
+++ b/ip6t_MAP66.c
@@ -126,17 +126,28 @@ static unsigned int MAP66_tg6(
&hdr->saddr, &hdr->daddr);
#endif
+ if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) {
+ pr_devel("MAP66: unwriteable, dropped\n");
+ return NF_DROP;
+ }
+ hdr = ipv6_hdr(skb);
+
if (0 != (IP6T_MAP66_OPT_DST_TO & info->mapflags)) {
- pr_devel("MAP66 DST, check=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags));
+ pr_devel("MAP66 DST, nocheck=%d, ip_summed=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags), skb->ip_summed);
if (0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags) ||
!is_my_ipv6_addr(par->in, &hdr->daddr))
{
- map16(&hdr->daddr, &info->pfix_dst_to, info->pfix_dst_len, info->pfix_dst_csum);
+ if (0 != (IP6T_MAP66_OPT_UNBALANCED & info->mapflags)) {
+ memcpy(&hdr->daddr, &info->pfix_dst_to, sizeof(u_int16_t) * info->pfix_dst_len);
+ }
+ else {
+ map16(&hdr->daddr, &info->pfix_dst_to, info->pfix_dst_len, info->pfix_dst_csum);
+ }
}
}
if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags)) {
- pr_devel("MAP66 SRC, check=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags));
+ pr_devel("MAP66 SRC, nocheck=%d, ip_summed=%d\n", 0 != (IP6T_MAP66_OPT_NOCHECK & info->mapflags), skb->ip_summed);
map16(&hdr->saddr, &info->pfix_src_to, info->pfix_src_len, info->pfix_src_csum);
if (0 == (IP6T_MAP66_OPT_NOCHECK & info->mapflags) &&
is_my_ipv6_addr(par->out, &hdr->saddr))
@@ -170,17 +181,27 @@ static bool MAP66_tg6_check(
return false;
}
- if (0 != (IP6T_MAP66_OPT_DST_TO & info->mapflags) &&
- (0 >= info->pfix_dst_len || 8 <= info->pfix_dst_len))
+ if (0 != (IP6T_MAP66_OPT_DST_TO & info->mapflags) && (0 >= info->pfix_dst_len ||
+ 0 != (IP6T_MAP66_OPT_UNBALANCED & info->mapflags) ? 8 : 7 < info->pfix_dst_len))
{
- printk("MAP66: Unsupported --" IP6T_MAP66_DST_TO " prefix length /%d\n", 16 * info->pfix_dst_len);
+ if (8 == info->pfix_dst_len) {
+ printk("MAP66: --" IP6T_MAP66_DST_TO " prefix length /%d only possible with --unbalanced\n", 16 * info->pfix_dst_len);
+ }
+ else {
+ printk("MAP66: Unsupported --" IP6T_MAP66_DST_TO " prefix length /%d\n", 16 * info->pfix_dst_len);
+ }
return false;
}
- if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags) &&
- (0 >= info->pfix_src_len || 8 <= info->pfix_src_len))
+ if (0 != (IP6T_MAP66_OPT_SRC_TO & info->mapflags) && (0 >= info->pfix_src_len ||
+ 0 != (IP6T_MAP66_OPT_UNBALANCED & info->mapflags) ? 8 : 7 < info->pfix_src_len))
{
- printk("MAP66: Unsupported --" IP6T_MAP66_SRC_TO " prefix length /%d\n", 16 * info->pfix_src_len);
+ if (8 == info->pfix_src_len) {
+ printk("MAP66: --" IP6T_MAP66_SRC_TO " prefix length /%d only possible with --unbalanced\n", 16 * info->pfix_src_len);
+ }
+ else {
+ printk("MAP66: Unsupported --" IP6T_MAP66_SRC_TO " prefix length /%d\n", 16 * info->pfix_src_len);
+ }
return false;
}
return true;