Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8a91bb0c
Commit
8a91bb0c
authored
Aug 26, 2012
by
Patrick McHardy
Committed by
Pablo Neira Ayuso
Aug 30, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
netfilter: ip6tables: add stateless IPv6-to-IPv6 Network Prefix Translation target
Signed-off-by:
Patrick McHardy
<
kaber@trash.net
>
parent
320ff567
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
192 additions
and
0 deletions
+192
-0
include/linux/netfilter_ipv6/Kbuild
include/linux/netfilter_ipv6/Kbuild
+1
-0
include/linux/netfilter_ipv6/ip6t_NPT.h
include/linux/netfilter_ipv6/ip6t_NPT.h
+16
-0
net/ipv6/netfilter/Kconfig
net/ipv6/netfilter/Kconfig
+9
-0
net/ipv6/netfilter/Makefile
net/ipv6/netfilter/Makefile
+1
-0
net/ipv6/netfilter/ip6t_NPT.c
net/ipv6/netfilter/ip6t_NPT.c
+165
-0
No files found.
include/linux/netfilter_ipv6/Kbuild
View file @
8a91bb0c
header-y += ip6_tables.h
header-y += ip6t_HL.h
header-y += ip6t_LOG.h
header-y += ip6t_NPT.h
header-y += ip6t_REJECT.h
header-y += ip6t_ah.h
header-y += ip6t_frag.h
...
...
include/linux/netfilter_ipv6/ip6t_NPT.h
0 → 100644
View file @
8a91bb0c
#ifndef __NETFILTER_IP6T_NPT
#define __NETFILTER_IP6T_NPT
#include <linux/types.h>
#include <linux/netfilter.h>
struct
ip6t_npt_tginfo
{
union
nf_inet_addr
src_pfx
;
union
nf_inet_addr
dst_pfx
;
__u8
src_pfx_len
;
__u8
dst_pfx_len
;
/* Used internally by the kernel */
__sum16
adjustment
;
};
#endif
/* __NETFILTER_IP6T_NPT */
net/ipv6/netfilter/Kconfig
View file @
8a91bb0c
...
...
@@ -177,6 +177,15 @@ config IP6_NF_TARGET_REDIRECT
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_TARGET_NPT
tristate "NPT (Network Prefix translation) target support"
depends on NETFILTER_ADVANCED
help
This option adds the `SNPT' and `DNPT' target, which perform
stateless IPv6-to-IPv6 Network Prefix Translation per RFC 6296.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_FILTER
tristate "Packet filtering"
default m if NETFILTER_ADVANCED=n
...
...
net/ipv6/netfilter/Makefile
View file @
8a91bb0c
...
...
@@ -36,5 +36,6 @@ obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
# targets
obj-$(CONFIG_IP6_NF_TARGET_MASQUERADE)
+=
ip6t_MASQUERADE.o
obj-$(CONFIG_IP6_NF_TARGET_NETMAP)
+=
ip6t_NETMAP.o
obj-$(CONFIG_IP6_NF_TARGET_NPT)
+=
ip6t_NPT.o
obj-$(CONFIG_IP6_NF_TARGET_REDIRECT)
+=
ip6t_REDIRECT.o
obj-$(CONFIG_IP6_NF_TARGET_REJECT)
+=
ip6t_REJECT.o
net/ipv6/netfilter/ip6t_NPT.c
0 → 100644
View file @
8a91bb0c
/*
* Copyright (c) 2011, 2012 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/module.h>
#include <linux/skbuff.h>
#include <linux/ipv6.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv6.h>
#include <linux/netfilter_ipv6/ip6t_NPT.h>
#include <linux/netfilter/x_tables.h>
static
__sum16
csum16_complement
(
__sum16
a
)
{
return
(
__force
__sum16
)(
0xffff
-
(
__force
u16
)
a
);
}
static
__sum16
csum16_add
(
__sum16
a
,
__sum16
b
)
{
u16
sum
;
sum
=
(
__force
u16
)
a
+
(
__force
u16
)
b
;
sum
+=
(
__force
u16
)
a
<
(
__force
u16
)
b
;
return
(
__force
__sum16
)
sum
;
}
static
__sum16
csum16_sub
(
__sum16
a
,
__sum16
b
)
{
return
csum16_add
(
a
,
csum16_complement
(
b
));
}
static
int
ip6t_npt_checkentry
(
const
struct
xt_tgchk_param
*
par
)
{
struct
ip6t_npt_tginfo
*
npt
=
par
->
targinfo
;
__sum16
src_sum
=
0
,
dst_sum
=
0
;
unsigned
int
i
;
if
(
npt
->
src_pfx_len
>
64
||
npt
->
dst_pfx_len
>
64
)
return
-
EINVAL
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
npt
->
src_pfx
.
in6
.
s6_addr16
);
i
++
)
{
src_sum
=
csum16_add
(
src_sum
,
(
__force
__sum16
)
npt
->
src_pfx
.
in6
.
s6_addr16
[
i
]);
dst_sum
=
csum16_add
(
dst_sum
,
(
__force
__sum16
)
npt
->
dst_pfx
.
in6
.
s6_addr16
[
i
]);
}
npt
->
adjustment
=
csum16_sub
(
src_sum
,
dst_sum
);
return
0
;
}
static
bool
ip6t_npt_map_pfx
(
const
struct
ip6t_npt_tginfo
*
npt
,
struct
in6_addr
*
addr
)
{
unsigned
int
pfx_len
;
unsigned
int
i
,
idx
;
__be32
mask
;
__sum16
sum
;
pfx_len
=
max
(
npt
->
src_pfx_len
,
npt
->
dst_pfx_len
);
for
(
i
=
0
;
i
<
pfx_len
;
i
+=
32
)
{
if
(
pfx_len
-
i
>=
32
)
mask
=
0
;
else
mask
=
htonl
(
~
((
1
<<
(
pfx_len
-
i
))
-
1
));
idx
=
i
/
32
;
addr
->
s6_addr32
[
idx
]
&=
mask
;
addr
->
s6_addr32
[
idx
]
|=
npt
->
dst_pfx
.
in6
.
s6_addr32
[
idx
];
}
if
(
pfx_len
<=
48
)
idx
=
3
;
else
{
for
(
idx
=
4
;
idx
<
ARRAY_SIZE
(
addr
->
s6_addr16
);
idx
++
)
{
if
((
__force
__sum16
)
addr
->
s6_addr16
[
idx
]
!=
CSUM_MANGLED_0
)
break
;
}
if
(
idx
==
ARRAY_SIZE
(
addr
->
s6_addr16
))
return
false
;
}
sum
=
csum16_add
((
__force
__sum16
)
addr
->
s6_addr16
[
idx
],
npt
->
adjustment
);
if
(
sum
==
CSUM_MANGLED_0
)
sum
=
0
;
*
(
__force
__sum16
*
)
&
addr
->
s6_addr16
[
idx
]
=
sum
;
return
true
;
}
static
unsigned
int
ip6t_snpt_tg
(
struct
sk_buff
*
skb
,
const
struct
xt_action_param
*
par
)
{
const
struct
ip6t_npt_tginfo
*
npt
=
par
->
targinfo
;
if
(
!
ip6t_npt_map_pfx
(
npt
,
&
ipv6_hdr
(
skb
)
->
saddr
))
{
icmpv6_send
(
skb
,
ICMPV6_PARAMPROB
,
ICMPV6_HDR_FIELD
,
offsetof
(
struct
ipv6hdr
,
saddr
));
return
NF_DROP
;
}
return
XT_CONTINUE
;
}
static
unsigned
int
ip6t_dnpt_tg
(
struct
sk_buff
*
skb
,
const
struct
xt_action_param
*
par
)
{
const
struct
ip6t_npt_tginfo
*
npt
=
par
->
targinfo
;
if
(
!
ip6t_npt_map_pfx
(
npt
,
&
ipv6_hdr
(
skb
)
->
daddr
))
{
icmpv6_send
(
skb
,
ICMPV6_PARAMPROB
,
ICMPV6_HDR_FIELD
,
offsetof
(
struct
ipv6hdr
,
daddr
));
return
NF_DROP
;
}
return
XT_CONTINUE
;
}
static
struct
xt_target
ip6t_npt_target_reg
[]
__read_mostly
=
{
{
.
name
=
"SNPT"
,
.
target
=
ip6t_snpt_tg
,
.
targetsize
=
sizeof
(
struct
ip6t_npt_tginfo
),
.
checkentry
=
ip6t_npt_checkentry
,
.
family
=
NFPROTO_IPV6
,
.
hooks
=
(
1
<<
NF_INET_LOCAL_IN
)
|
(
1
<<
NF_INET_POST_ROUTING
),
.
me
=
THIS_MODULE
,
},
{
.
name
=
"DNPT"
,
.
target
=
ip6t_dnpt_tg
,
.
targetsize
=
sizeof
(
struct
ip6t_npt_tginfo
),
.
checkentry
=
ip6t_npt_checkentry
,
.
family
=
NFPROTO_IPV6
,
.
hooks
=
(
1
<<
NF_INET_PRE_ROUTING
)
|
(
1
<<
NF_INET_LOCAL_OUT
),
.
me
=
THIS_MODULE
,
},
};
static
int
__init
ip6t_npt_init
(
void
)
{
return
xt_register_targets
(
ip6t_npt_target_reg
,
ARRAY_SIZE
(
ip6t_npt_target_reg
));
}
static
void
__exit
ip6t_npt_exit
(
void
)
{
xt_unregister_targets
(
ip6t_npt_target_reg
,
ARRAY_SIZE
(
ip6t_npt_target_reg
));
}
module_init
(
ip6t_npt_init
);
module_exit
(
ip6t_npt_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"IPv6-to-IPv6 Network Prefix Translation (RFC 6296)"
);
MODULE_AUTHOR
(
"Patrick McHardy <kaber@trash.net>"
);
MODULE_ALIAS
(
"ip6t_SNPT"
);
MODULE_ALIAS
(
"ip6t_DNPT"
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment