Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
a49d1a90
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
a49d1a90
编写于
12年前
作者:
D
David S. Miller
浏览文件
操作
浏览文件
下载
差异文件
Merge
git://1984.lsi.us.es/net-next
上级
2e7d21c5
0197dee7
无相关合并请求
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
588 addition
and
46 deletion
+588
-46
include/linux/netfilter/xt_HMARK.h
include/linux/netfilter/xt_HMARK.h
+45
-0
include/linux/netfilter/xt_hashlimit.h
include/linux/netfilter/xt_hashlimit.h
+9
-1
include/linux/netfilter_ipv6/ip6_tables.h
include/linux/netfilter_ipv6/ip6_tables.h
+6
-1
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6_tables.c
+31
-5
net/ipv6/netfilter/ip6t_ah.c
net/ipv6/netfilter/ip6t_ah.c
+2
-2
net/ipv6/netfilter/ip6t_frag.c
net/ipv6/netfilter/ip6t_frag.c
+2
-2
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/netfilter/ip6t_hbh.c
+2
-2
net/ipv6/netfilter/ip6t_rt.c
net/ipv6/netfilter/ip6t_rt.c
+2
-2
net/netfilter/Kconfig
net/netfilter/Kconfig
+15
-0
net/netfilter/Makefile
net/netfilter/Makefile
+1
-0
net/netfilter/xt_HMARK.c
net/netfilter/xt_HMARK.c
+362
-0
net/netfilter/xt_TPROXY.c
net/netfilter/xt_TPROXY.c
+2
-2
net/netfilter/xt_hashlimit.c
net/netfilter/xt_hashlimit.c
+105
-24
net/netfilter/xt_limit.c
net/netfilter/xt_limit.c
+2
-3
net/netfilter/xt_socket.c
net/netfilter/xt_socket.c
+2
-2
未找到文件。
include/linux/netfilter/xt_HMARK.h
0 → 100644
浏览文件 @
a49d1a90
#ifndef XT_HMARK_H_
#define XT_HMARK_H_
#include <linux/types.h>
enum
{
XT_HMARK_SADDR_MASK
,
XT_HMARK_DADDR_MASK
,
XT_HMARK_SPI
,
XT_HMARK_SPI_MASK
,
XT_HMARK_SPORT
,
XT_HMARK_DPORT
,
XT_HMARK_SPORT_MASK
,
XT_HMARK_DPORT_MASK
,
XT_HMARK_PROTO_MASK
,
XT_HMARK_RND
,
XT_HMARK_MODULUS
,
XT_HMARK_OFFSET
,
XT_HMARK_CT
,
XT_HMARK_METHOD_L3
,
XT_HMARK_METHOD_L3_4
,
};
#define XT_HMARK_FLAG(flag) (1 << flag)
union
hmark_ports
{
struct
{
__u16
src
;
__u16
dst
;
}
p16
;
__u32
v32
;
};
struct
xt_hmark_info
{
union
nf_inet_addr
src_mask
;
union
nf_inet_addr
dst_mask
;
union
hmark_ports
port_mask
;
union
hmark_ports
port_set
;
__u32
flags
;
__u16
proto_mask
;
__u32
hashrnd
;
__u32
hmodulus
;
__u32
hoffset
;
/* Mark offset to start from */
};
#endif
/* XT_HMARK_H_ */
This diff is collapsed.
Click to expand it.
include/linux/netfilter/xt_hashlimit.h
浏览文件 @
a49d1a90
...
...
@@ -6,7 +6,11 @@
/* timings are in milliseconds. */
#define XT_HASHLIMIT_SCALE 10000
/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490
seconds, or one every 59 hours. */
* seconds, or one packet every 59 hours.
*/
/* packet length accounting is done in 16-byte steps */
#define XT_HASHLIMIT_BYTE_SHIFT 4
/* details of this structure hidden by the implementation */
struct
xt_hashlimit_htable
;
...
...
@@ -17,6 +21,10 @@ enum {
XT_HASHLIMIT_HASH_SIP
=
1
<<
2
,
XT_HASHLIMIT_HASH_SPT
=
1
<<
3
,
XT_HASHLIMIT_INVERT
=
1
<<
4
,
XT_HASHLIMIT_BYTES
=
1
<<
5
,
#ifdef __KERNEL__
XT_HASHLIMIT_MAX
=
1
<<
6
,
#endif
};
struct
hashlimit_cfg
{
...
...
This diff is collapsed.
Click to expand it.
include/linux/netfilter_ipv6/ip6_tables.h
浏览文件 @
a49d1a90
...
...
@@ -298,9 +298,14 @@ ip6t_ext_hdr(u8 nexthdr)
(
nexthdr
==
IPPROTO_DSTOPTS
);
}
enum
{
IP6T_FH_F_FRAG
=
(
1
<<
0
),
IP6T_FH_F_AUTH
=
(
1
<<
1
),
};
/* find specified header and get offset to it */
extern
int
ipv6_find_hdr
(
const
struct
sk_buff
*
skb
,
unsigned
int
*
offset
,
int
target
,
unsigned
short
*
fragoff
);
int
target
,
unsigned
short
*
fragoff
,
int
*
fragflg
);
#ifdef CONFIG_COMPAT
#include <net/compat.h>
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6_tables.c
浏览文件 @
a49d1a90
...
...
@@ -133,7 +133,7 @@ ip6_packet_match(const struct sk_buff *skb,
int
protohdr
;
unsigned
short
_frag_off
;
protohdr
=
ipv6_find_hdr
(
skb
,
protoff
,
-
1
,
&
_frag_off
);
protohdr
=
ipv6_find_hdr
(
skb
,
protoff
,
-
1
,
&
_frag_off
,
NULL
);
if
(
protohdr
<
0
)
{
if
(
_frag_off
==
0
)
*
hotdrop
=
true
;
...
...
@@ -362,6 +362,7 @@ ip6t_do_table(struct sk_buff *skb,
const
struct
xt_entry_match
*
ematch
;
IP_NF_ASSERT
(
e
);
acpar
.
thoff
=
0
;
if
(
!
ip6_packet_match
(
skb
,
indev
,
outdev
,
&
e
->
ipv6
,
&
acpar
.
thoff
,
&
acpar
.
fragoff
,
&
acpar
.
hotdrop
))
{
no_match:
...
...
@@ -2278,6 +2279,10 @@ static void __exit ip6_tables_fini(void)
* if target < 0. "last header" is transport protocol header, ESP, or
* "No next header".
*
* Note that *offset is used as input/output parameter. an if it is not zero,
* then it must be a valid offset to an inner IPv6 header. This can be used
* to explore inner IPv6 header, eg. ICMPv6 error messages.
*
* If target header is found, its offset is set in *offset and return protocol
* number. Otherwise, return -1.
*
...
...
@@ -2289,17 +2294,33 @@ static void __exit ip6_tables_fini(void)
* *offset is meaningless and fragment offset is stored in *fragoff if fragoff
* isn't NULL.
*
* if flags is not NULL and it's a fragment, then the frag flag IP6T_FH_F_FRAG
* will be set. If it's an AH header, the IP6T_FH_F_AUTH flag is set and
* target < 0, then this function will stop at the AH header.
*/
int
ipv6_find_hdr
(
const
struct
sk_buff
*
skb
,
unsigned
int
*
offset
,
int
target
,
unsigned
short
*
fragoff
)
int
target
,
unsigned
short
*
fragoff
,
int
*
flags
)
{
unsigned
int
start
=
skb_network_offset
(
skb
)
+
sizeof
(
struct
ipv6hdr
);
u8
nexthdr
=
ipv6_hdr
(
skb
)
->
nexthdr
;
unsigned
int
len
=
skb
->
len
-
start
;
unsigned
int
len
;
if
(
fragoff
)
*
fragoff
=
0
;
if
(
*
offset
)
{
struct
ipv6hdr
_ip6
,
*
ip6
;
ip6
=
skb_header_pointer
(
skb
,
*
offset
,
sizeof
(
_ip6
),
&
_ip6
);
if
(
!
ip6
||
(
ip6
->
version
!=
6
))
{
printk
(
KERN_ERR
"IPv6 header not found
\n
"
);
return
-
EBADMSG
;
}
start
=
*
offset
+
sizeof
(
struct
ipv6hdr
);
nexthdr
=
ip6
->
nexthdr
;
}
len
=
skb
->
len
-
start
;
while
(
nexthdr
!=
target
)
{
struct
ipv6_opt_hdr
_hdr
,
*
hp
;
unsigned
int
hdrlen
;
...
...
@@ -2316,6 +2337,9 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
if
(
nexthdr
==
NEXTHDR_FRAGMENT
)
{
unsigned
short
_frag_off
;
__be16
*
fp
;
if
(
flags
)
/* Indicate that this is a fragment */
*
flags
|=
IP6T_FH_F_FRAG
;
fp
=
skb_header_pointer
(
skb
,
start
+
offsetof
(
struct
frag_hdr
,
frag_off
),
...
...
@@ -2336,9 +2360,11 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
return
-
ENOENT
;
}
hdrlen
=
8
;
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
}
else
if
(
nexthdr
==
NEXTHDR_AUTH
)
{
if
(
flags
&&
(
*
flags
&
IP6T_FH_F_AUTH
)
&&
(
target
<
0
))
break
;
hdrlen
=
(
hp
->
hdrlen
+
2
)
<<
2
;
else
}
else
hdrlen
=
ipv6_optlen
(
hp
);
nexthdr
=
hp
->
nexthdr
;
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6t_ah.c
浏览文件 @
a49d1a90
...
...
@@ -41,11 +41,11 @@ static bool ah_mt6(const struct sk_buff *skb, struct xt_action_param *par)
struct
ip_auth_hdr
_ah
;
const
struct
ip_auth_hdr
*
ah
;
const
struct
ip6t_ah
*
ahinfo
=
par
->
matchinfo
;
unsigned
int
ptr
;
unsigned
int
ptr
=
0
;
unsigned
int
hdrlen
=
0
;
int
err
;
err
=
ipv6_find_hdr
(
skb
,
&
ptr
,
NEXTHDR_AUTH
,
NULL
);
err
=
ipv6_find_hdr
(
skb
,
&
ptr
,
NEXTHDR_AUTH
,
NULL
,
NULL
);
if
(
err
<
0
)
{
if
(
err
!=
-
ENOENT
)
par
->
hotdrop
=
true
;
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6t_frag.c
浏览文件 @
a49d1a90
...
...
@@ -40,10 +40,10 @@ frag_mt6(const struct sk_buff *skb, struct xt_action_param *par)
struct
frag_hdr
_frag
;
const
struct
frag_hdr
*
fh
;
const
struct
ip6t_frag
*
fraginfo
=
par
->
matchinfo
;
unsigned
int
ptr
;
unsigned
int
ptr
=
0
;
int
err
;
err
=
ipv6_find_hdr
(
skb
,
&
ptr
,
NEXTHDR_FRAGMENT
,
NULL
);
err
=
ipv6_find_hdr
(
skb
,
&
ptr
,
NEXTHDR_FRAGMENT
,
NULL
,
NULL
);
if
(
err
<
0
)
{
if
(
err
!=
-
ENOENT
)
par
->
hotdrop
=
true
;
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6t_hbh.c
浏览文件 @
a49d1a90
...
...
@@ -50,7 +50,7 @@ hbh_mt6(const struct sk_buff *skb, struct xt_action_param *par)
const
struct
ipv6_opt_hdr
*
oh
;
const
struct
ip6t_opts
*
optinfo
=
par
->
matchinfo
;
unsigned
int
temp
;
unsigned
int
ptr
;
unsigned
int
ptr
=
0
;
unsigned
int
hdrlen
=
0
;
bool
ret
=
false
;
u8
_opttype
;
...
...
@@ -62,7 +62,7 @@ hbh_mt6(const struct sk_buff *skb, struct xt_action_param *par)
err
=
ipv6_find_hdr
(
skb
,
&
ptr
,
(
par
->
match
==
&
hbh_mt6_reg
[
0
])
?
NEXTHDR_HOP
:
NEXTHDR_DEST
,
NULL
);
NEXTHDR_HOP
:
NEXTHDR_DEST
,
NULL
,
NULL
);
if
(
err
<
0
)
{
if
(
err
!=
-
ENOENT
)
par
->
hotdrop
=
true
;
...
...
This diff is collapsed.
Click to expand it.
net/ipv6/netfilter/ip6t_rt.c
浏览文件 @
a49d1a90
...
...
@@ -42,14 +42,14 @@ static bool rt_mt6(const struct sk_buff *skb, struct xt_action_param *par)
const
struct
ipv6_rt_hdr
*
rh
;
const
struct
ip6t_rt
*
rtinfo
=
par
->
matchinfo
;
unsigned
int
temp
;
unsigned
int
ptr
;
unsigned
int
ptr
=
0
;
unsigned
int
hdrlen
=
0
;
bool
ret
=
false
;
struct
in6_addr
_addr
;
const
struct
in6_addr
*
ap
;
int
err
;
err
=
ipv6_find_hdr
(
skb
,
&
ptr
,
NEXTHDR_ROUTING
,
NULL
);
err
=
ipv6_find_hdr
(
skb
,
&
ptr
,
NEXTHDR_ROUTING
,
NULL
,
NULL
);
if
(
err
<
0
)
{
if
(
err
!=
-
ENOENT
)
par
->
hotdrop
=
true
;
...
...
This diff is collapsed.
Click to expand it.
net/netfilter/Kconfig
浏览文件 @
a49d1a90
...
...
@@ -509,6 +509,21 @@ config NETFILTER_XT_TARGET_HL
since you can easily create immortal packets that loop
forever on the network.
config NETFILTER_XT_TARGET_HMARK
tristate '"HMARK" target support'
depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
depends on NETFILTER_ADVANCED
---help---
This option adds the "HMARK" target.
The target allows you to create rules in the "raw" and "mangle" tables
which set the skbuff mark by means of hash calculation within a given
range. The nfmark can influence the routing method (see "Use netfilter
MARK value as routing key") and can also be used by other subsystems to
change their behaviour.
To compile it as a module, choose M here. If unsure, say N.
config NETFILTER_XT_TARGET_IDLETIMER
tristate "IDLETIMER target support"
depends on NETFILTER_ADVANCED
...
...
This diff is collapsed.
Click to expand it.
net/netfilter/Makefile
浏览文件 @
a49d1a90
...
...
@@ -59,6 +59,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_CT)
+=
xt_CT.o
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP)
+=
xt_DSCP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_HL)
+=
xt_HL.o
obj-$(CONFIG_NETFILTER_XT_TARGET_HMARK)
+=
xt_HMARK.o
obj-$(CONFIG_NETFILTER_XT_TARGET_LED)
+=
xt_LED.o
obj-$(CONFIG_NETFILTER_XT_TARGET_LOG)
+=
xt_LOG.o
obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG)
+=
xt_NFLOG.o
...
...
This diff is collapsed.
Click to expand it.
net/netfilter/xt_HMARK.c
0 → 100644
浏览文件 @
a49d1a90
/*
* xt_HMARK - Netfilter module to set mark by means of hashing
*
* (C) 2012 by Hans Schillstrom <hans.schillstrom@ericsson.com>
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* 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/icmp.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/xt_HMARK.h>
#include <net/ip.h>
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
#include <net/netfilter/nf_conntrack.h>
#endif
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
#include <net/ipv6.h>
#include <linux/netfilter_ipv6/ip6_tables.h>
#endif
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Hans Schillstrom <hans.schillstrom@ericsson.com>"
);
MODULE_DESCRIPTION
(
"Xtables: packet marking using hash calculation"
);
MODULE_ALIAS
(
"ipt_HMARK"
);
MODULE_ALIAS
(
"ip6t_HMARK"
);
struct
hmark_tuple
{
u32
src
;
u32
dst
;
union
hmark_ports
uports
;
uint8_t
proto
;
};
static
inline
u32
hmark_addr6_mask
(
const
__u32
*
addr32
,
const
__u32
*
mask
)
{
return
(
addr32
[
0
]
&
mask
[
0
])
^
(
addr32
[
1
]
&
mask
[
1
])
^
(
addr32
[
2
]
&
mask
[
2
])
^
(
addr32
[
3
]
&
mask
[
3
]);
}
static
inline
u32
hmark_addr_mask
(
int
l3num
,
const
__u32
*
addr32
,
const
__u32
*
mask
)
{
switch
(
l3num
)
{
case
AF_INET
:
return
*
addr32
&
*
mask
;
case
AF_INET6
:
return
hmark_addr6_mask
(
addr32
,
mask
);
}
return
0
;
}
static
int
hmark_ct_set_htuple
(
const
struct
sk_buff
*
skb
,
struct
hmark_tuple
*
t
,
const
struct
xt_hmark_info
*
info
)
{
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
enum
ip_conntrack_info
ctinfo
;
struct
nf_conn
*
ct
=
nf_ct_get
(
skb
,
&
ctinfo
);
struct
nf_conntrack_tuple
*
otuple
;
struct
nf_conntrack_tuple
*
rtuple
;
if
(
ct
==
NULL
||
nf_ct_is_untracked
(
ct
))
return
-
1
;
otuple
=
&
ct
->
tuplehash
[
IP_CT_DIR_ORIGINAL
].
tuple
;
rtuple
=
&
ct
->
tuplehash
[
IP_CT_DIR_REPLY
].
tuple
;
t
->
src
=
hmark_addr_mask
(
otuple
->
src
.
l3num
,
otuple
->
src
.
u3
.
all
,
info
->
src_mask
.
all
);
t
->
dst
=
hmark_addr_mask
(
otuple
->
src
.
l3num
,
rtuple
->
src
.
u3
.
all
,
info
->
dst_mask
.
all
);
if
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_METHOD_L3
))
return
0
;
t
->
proto
=
nf_ct_protonum
(
ct
);
if
(
t
->
proto
!=
IPPROTO_ICMP
)
{
t
->
uports
.
p16
.
src
=
otuple
->
src
.
u
.
all
;
t
->
uports
.
p16
.
dst
=
rtuple
->
src
.
u
.
all
;
t
->
uports
.
v32
=
(
t
->
uports
.
v32
&
info
->
port_mask
.
v32
)
|
info
->
port_set
.
v32
;
if
(
t
->
uports
.
p16
.
dst
<
t
->
uports
.
p16
.
src
)
swap
(
t
->
uports
.
p16
.
dst
,
t
->
uports
.
p16
.
src
);
}
return
0
;
#else
return
-
1
;
#endif
}
static
inline
u32
hmark_hash
(
struct
hmark_tuple
*
t
,
const
struct
xt_hmark_info
*
info
)
{
u32
hash
;
if
(
t
->
dst
<
t
->
src
)
swap
(
t
->
src
,
t
->
dst
);
hash
=
jhash_3words
(
t
->
src
,
t
->
dst
,
t
->
uports
.
v32
,
info
->
hashrnd
);
hash
=
hash
^
(
t
->
proto
&
info
->
proto_mask
);
return
(
hash
%
info
->
hmodulus
)
+
info
->
hoffset
;
}
static
void
hmark_set_tuple_ports
(
const
struct
sk_buff
*
skb
,
unsigned
int
nhoff
,
struct
hmark_tuple
*
t
,
const
struct
xt_hmark_info
*
info
)
{
int
protoff
;
protoff
=
proto_ports_offset
(
t
->
proto
);
if
(
protoff
<
0
)
return
;
nhoff
+=
protoff
;
if
(
skb_copy_bits
(
skb
,
nhoff
,
&
t
->
uports
,
sizeof
(
t
->
uports
))
<
0
)
return
;
t
->
uports
.
v32
=
(
t
->
uports
.
v32
&
info
->
port_mask
.
v32
)
|
info
->
port_set
.
v32
;
if
(
t
->
uports
.
p16
.
dst
<
t
->
uports
.
p16
.
src
)
swap
(
t
->
uports
.
p16
.
dst
,
t
->
uports
.
p16
.
src
);
}
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
static
int
get_inner6_hdr
(
const
struct
sk_buff
*
skb
,
int
*
offset
)
{
struct
icmp6hdr
*
icmp6h
,
_ih6
;
icmp6h
=
skb_header_pointer
(
skb
,
*
offset
,
sizeof
(
_ih6
),
&
_ih6
);
if
(
icmp6h
==
NULL
)
return
0
;
if
(
icmp6h
->
icmp6_type
&&
icmp6h
->
icmp6_type
<
128
)
{
*
offset
+=
sizeof
(
struct
icmp6hdr
);
return
1
;
}
return
0
;
}
static
int
hmark_pkt_set_htuple_ipv6
(
const
struct
sk_buff
*
skb
,
struct
hmark_tuple
*
t
,
const
struct
xt_hmark_info
*
info
)
{
struct
ipv6hdr
*
ip6
,
_ip6
;
int
flag
=
IP6T_FH_F_AUTH
;
unsigned
int
nhoff
=
0
;
u16
fragoff
=
0
;
int
nexthdr
;
ip6
=
(
struct
ipv6hdr
*
)
(
skb
->
data
+
skb_network_offset
(
skb
));
nexthdr
=
ipv6_find_hdr
(
skb
,
&
nhoff
,
-
1
,
&
fragoff
,
&
flag
);
if
(
nexthdr
<
0
)
return
0
;
/* No need to check for icmp errors on fragments */
if
((
flag
&
IP6T_FH_F_FRAG
)
||
(
nexthdr
!=
IPPROTO_ICMPV6
))
goto
noicmp
;
/* Use inner header in case of ICMP errors */
if
(
get_inner6_hdr
(
skb
,
&
nhoff
))
{
ip6
=
skb_header_pointer
(
skb
,
nhoff
,
sizeof
(
_ip6
),
&
_ip6
);
if
(
ip6
==
NULL
)
return
-
1
;
/* If AH present, use SPI like in ESP. */
flag
=
IP6T_FH_F_AUTH
;
nexthdr
=
ipv6_find_hdr
(
skb
,
&
nhoff
,
-
1
,
&
fragoff
,
&
flag
);
if
(
nexthdr
<
0
)
return
-
1
;
}
noicmp:
t
->
src
=
hmark_addr6_mask
(
ip6
->
saddr
.
s6_addr32
,
info
->
src_mask
.
all
);
t
->
dst
=
hmark_addr6_mask
(
ip6
->
daddr
.
s6_addr32
,
info
->
dst_mask
.
all
);
if
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_METHOD_L3
))
return
0
;
t
->
proto
=
nexthdr
;
if
(
t
->
proto
==
IPPROTO_ICMPV6
)
return
0
;
if
(
flag
&
IP6T_FH_F_FRAG
)
return
0
;
hmark_set_tuple_ports
(
skb
,
nhoff
,
t
,
info
);
return
0
;
}
static
unsigned
int
hmark_tg_v6
(
struct
sk_buff
*
skb
,
const
struct
xt_action_param
*
par
)
{
const
struct
xt_hmark_info
*
info
=
par
->
targinfo
;
struct
hmark_tuple
t
;
memset
(
&
t
,
0
,
sizeof
(
struct
hmark_tuple
));
if
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_CT
))
{
if
(
hmark_ct_set_htuple
(
skb
,
&
t
,
info
)
<
0
)
return
XT_CONTINUE
;
}
else
{
if
(
hmark_pkt_set_htuple_ipv6
(
skb
,
&
t
,
info
)
<
0
)
return
XT_CONTINUE
;
}
skb
->
mark
=
hmark_hash
(
&
t
,
info
);
return
XT_CONTINUE
;
}
#endif
static
int
get_inner_hdr
(
const
struct
sk_buff
*
skb
,
int
iphsz
,
int
*
nhoff
)
{
const
struct
icmphdr
*
icmph
;
struct
icmphdr
_ih
;
/* Not enough header? */
icmph
=
skb_header_pointer
(
skb
,
*
nhoff
+
iphsz
,
sizeof
(
_ih
),
&
_ih
);
if
(
icmph
==
NULL
&&
icmph
->
type
>
NR_ICMP_TYPES
)
return
0
;
/* Error message? */
if
(
icmph
->
type
!=
ICMP_DEST_UNREACH
&&
icmph
->
type
!=
ICMP_SOURCE_QUENCH
&&
icmph
->
type
!=
ICMP_TIME_EXCEEDED
&&
icmph
->
type
!=
ICMP_PARAMETERPROB
&&
icmph
->
type
!=
ICMP_REDIRECT
)
return
0
;
*
nhoff
+=
iphsz
+
sizeof
(
_ih
);
return
1
;
}
static
int
hmark_pkt_set_htuple_ipv4
(
const
struct
sk_buff
*
skb
,
struct
hmark_tuple
*
t
,
const
struct
xt_hmark_info
*
info
)
{
struct
iphdr
*
ip
,
_ip
;
int
nhoff
=
skb_network_offset
(
skb
);
ip
=
(
struct
iphdr
*
)
(
skb
->
data
+
nhoff
);
if
(
ip
->
protocol
==
IPPROTO_ICMP
)
{
/* Use inner header in case of ICMP errors */
if
(
get_inner_hdr
(
skb
,
ip
->
ihl
*
4
,
&
nhoff
))
{
ip
=
skb_header_pointer
(
skb
,
nhoff
,
sizeof
(
_ip
),
&
_ip
);
if
(
ip
==
NULL
)
return
-
1
;
}
}
t
->
src
=
(
__force
u32
)
ip
->
saddr
;
t
->
dst
=
(
__force
u32
)
ip
->
daddr
;
t
->
src
&=
info
->
src_mask
.
ip
;
t
->
dst
&=
info
->
dst_mask
.
ip
;
if
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_METHOD_L3
))
return
0
;
t
->
proto
=
ip
->
protocol
;
/* ICMP has no ports, skip */
if
(
t
->
proto
==
IPPROTO_ICMP
)
return
0
;
/* follow-up fragments don't contain ports, skip all fragments */
if
(
ip
->
frag_off
&
htons
(
IP_MF
|
IP_OFFSET
))
return
0
;
hmark_set_tuple_ports
(
skb
,
(
ip
->
ihl
*
4
)
+
nhoff
,
t
,
info
);
return
0
;
}
static
unsigned
int
hmark_tg_v4
(
struct
sk_buff
*
skb
,
const
struct
xt_action_param
*
par
)
{
const
struct
xt_hmark_info
*
info
=
par
->
targinfo
;
struct
hmark_tuple
t
;
memset
(
&
t
,
0
,
sizeof
(
struct
hmark_tuple
));
if
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_CT
))
{
if
(
hmark_ct_set_htuple
(
skb
,
&
t
,
info
)
<
0
)
return
XT_CONTINUE
;
}
else
{
if
(
hmark_pkt_set_htuple_ipv4
(
skb
,
&
t
,
info
)
<
0
)
return
XT_CONTINUE
;
}
skb
->
mark
=
hmark_hash
(
&
t
,
info
);
return
XT_CONTINUE
;
}
static
int
hmark_tg_check
(
const
struct
xt_tgchk_param
*
par
)
{
const
struct
xt_hmark_info
*
info
=
par
->
targinfo
;
if
(
!
info
->
hmodulus
)
{
pr_info
(
"xt_HMARK: hash modulus can't be zero
\n
"
);
return
-
EINVAL
;
}
if
(
info
->
proto_mask
&&
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_METHOD_L3
)))
{
pr_info
(
"xt_HMARK: proto mask must be zero with L3 mode
\n
"
);
return
-
EINVAL
;
}
if
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_SPI_MASK
)
&&
(
info
->
flags
&
(
XT_HMARK_FLAG
(
XT_HMARK_SPORT_MASK
)
|
XT_HMARK_FLAG
(
XT_HMARK_DPORT_MASK
))))
{
pr_info
(
"xt_HMARK: spi-mask and port-mask can't be combined
\n
"
);
return
-
EINVAL
;
}
if
(
info
->
flags
&
XT_HMARK_FLAG
(
XT_HMARK_SPI
)
&&
(
info
->
flags
&
(
XT_HMARK_FLAG
(
XT_HMARK_SPORT
)
|
XT_HMARK_FLAG
(
XT_HMARK_DPORT
))))
{
pr_info
(
"xt_HMARK: spi-set and port-set can't be combined
\n
"
);
return
-
EINVAL
;
}
return
0
;
}
static
struct
xt_target
hmark_tg_reg
[]
__read_mostly
=
{
{
.
name
=
"HMARK"
,
.
family
=
NFPROTO_IPV4
,
.
target
=
hmark_tg_v4
,
.
targetsize
=
sizeof
(
struct
xt_hmark_info
),
.
checkentry
=
hmark_tg_check
,
.
me
=
THIS_MODULE
,
},
#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
{
.
name
=
"HMARK"
,
.
family
=
NFPROTO_IPV6
,
.
target
=
hmark_tg_v6
,
.
targetsize
=
sizeof
(
struct
xt_hmark_info
),
.
checkentry
=
hmark_tg_check
,
.
me
=
THIS_MODULE
,
},
#endif
};
static
int
__init
hmark_tg_init
(
void
)
{
return
xt_register_targets
(
hmark_tg_reg
,
ARRAY_SIZE
(
hmark_tg_reg
));
}
static
void
__exit
hmark_tg_exit
(
void
)
{
xt_unregister_targets
(
hmark_tg_reg
,
ARRAY_SIZE
(
hmark_tg_reg
));
}
module_init
(
hmark_tg_init
);
module_exit
(
hmark_tg_exit
);
This diff is collapsed.
Click to expand it.
net/netfilter/xt_TPROXY.c
浏览文件 @
a49d1a90
...
...
@@ -282,10 +282,10 @@ tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par)
struct
sock
*
sk
;
const
struct
in6_addr
*
laddr
;
__be16
lport
;
int
thoff
;
int
thoff
=
0
;
int
tproto
;
tproto
=
ipv6_find_hdr
(
skb
,
&
thoff
,
-
1
,
NULL
);
tproto
=
ipv6_find_hdr
(
skb
,
&
thoff
,
-
1
,
NULL
,
NULL
);
if
(
tproto
<
0
)
{
pr_debug
(
"unable to find transport header in IPv6 packet, dropping
\n
"
);
return
NF_DROP
;
...
...
This diff is collapsed.
Click to expand it.
net/netfilter/xt_hashlimit.c
浏览文件 @
a49d1a90
...
...
@@ -388,9 +388,20 @@ static void htable_put(struct xt_hashlimit_htable *hinfo)
#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
/* in byte mode, the lowest possible rate is one packet/second.
* credit_cap is used as a counter that tells us how many times we can
* refill the "credits available" counter when it becomes empty.
*/
#define MAX_CPJ_BYTES (0xFFFFFFFF / HZ)
#define CREDITS_PER_JIFFY_BYTES POW2_BELOW32(MAX_CPJ_BYTES)
static
u32
xt_hashlimit_len_to_chunks
(
u32
len
)
{
return
(
len
>>
XT_HASHLIMIT_BYTE_SHIFT
)
+
1
;
}
/* Precision saver. */
static
inline
u_int32_t
user2credits
(
u_int32_t
user
)
static
u32
user2credits
(
u32
user
)
{
/* If multiplying would overflow... */
if
(
user
>
0xFFFFFFFF
/
(
HZ
*
CREDITS_PER_JIFFY
))
...
...
@@ -400,12 +411,53 @@ user2credits(u_int32_t user)
return
(
user
*
HZ
*
CREDITS_PER_JIFFY
)
/
XT_HASHLIMIT_SCALE
;
}
static
inline
void
rateinfo_recalc
(
struct
dsthash_ent
*
dh
,
unsigned
long
now
)
static
u32
user2credits_byte
(
u32
user
)
{
dh
->
rateinfo
.
credit
+=
(
now
-
dh
->
rateinfo
.
prev
)
*
CREDITS_PER_JIFFY
;
if
(
dh
->
rateinfo
.
credit
>
dh
->
rateinfo
.
credit_cap
)
dh
->
rateinfo
.
credit
=
dh
->
rateinfo
.
credit_cap
;
u64
us
=
user
;
us
*=
HZ
*
CREDITS_PER_JIFFY_BYTES
;
return
(
u32
)
(
us
>>
32
);
}
static
void
rateinfo_recalc
(
struct
dsthash_ent
*
dh
,
unsigned
long
now
,
u32
mode
)
{
unsigned
long
delta
=
now
-
dh
->
rateinfo
.
prev
;
u32
cap
;
if
(
delta
==
0
)
return
;
dh
->
rateinfo
.
prev
=
now
;
if
(
mode
&
XT_HASHLIMIT_BYTES
)
{
u32
tmp
=
dh
->
rateinfo
.
credit
;
dh
->
rateinfo
.
credit
+=
CREDITS_PER_JIFFY_BYTES
*
delta
;
cap
=
CREDITS_PER_JIFFY_BYTES
*
HZ
;
if
(
tmp
>=
dh
->
rateinfo
.
credit
)
{
/* overflow */
dh
->
rateinfo
.
credit
=
cap
;
return
;
}
}
else
{
dh
->
rateinfo
.
credit
+=
delta
*
CREDITS_PER_JIFFY
;
cap
=
dh
->
rateinfo
.
credit_cap
;
}
if
(
dh
->
rateinfo
.
credit
>
cap
)
dh
->
rateinfo
.
credit
=
cap
;
}
static
void
rateinfo_init
(
struct
dsthash_ent
*
dh
,
struct
xt_hashlimit_htable
*
hinfo
)
{
dh
->
rateinfo
.
prev
=
jiffies
;
if
(
hinfo
->
cfg
.
mode
&
XT_HASHLIMIT_BYTES
)
{
dh
->
rateinfo
.
credit
=
CREDITS_PER_JIFFY_BYTES
*
HZ
;
dh
->
rateinfo
.
cost
=
user2credits_byte
(
hinfo
->
cfg
.
avg
);
dh
->
rateinfo
.
credit_cap
=
hinfo
->
cfg
.
burst
;
}
else
{
dh
->
rateinfo
.
credit
=
user2credits
(
hinfo
->
cfg
.
avg
*
hinfo
->
cfg
.
burst
);
dh
->
rateinfo
.
cost
=
user2credits
(
hinfo
->
cfg
.
avg
);
dh
->
rateinfo
.
credit_cap
=
dh
->
rateinfo
.
credit
;
}
}
static
inline
__be32
maskl
(
__be32
a
,
unsigned
int
l
)
...
...
@@ -511,6 +563,21 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
return
0
;
}
static
u32
hashlimit_byte_cost
(
unsigned
int
len
,
struct
dsthash_ent
*
dh
)
{
u64
tmp
=
xt_hashlimit_len_to_chunks
(
len
);
tmp
=
tmp
*
dh
->
rateinfo
.
cost
;
if
(
unlikely
(
tmp
>
CREDITS_PER_JIFFY_BYTES
*
HZ
))
tmp
=
CREDITS_PER_JIFFY_BYTES
*
HZ
;
if
(
dh
->
rateinfo
.
credit
<
tmp
&&
dh
->
rateinfo
.
credit_cap
)
{
dh
->
rateinfo
.
credit_cap
--
;
dh
->
rateinfo
.
credit
=
CREDITS_PER_JIFFY_BYTES
*
HZ
;
}
return
(
u32
)
tmp
;
}
static
bool
hashlimit_mt
(
const
struct
sk_buff
*
skb
,
struct
xt_action_param
*
par
)
{
...
...
@@ -519,6 +586,7 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
unsigned
long
now
=
jiffies
;
struct
dsthash_ent
*
dh
;
struct
dsthash_dst
dst
;
u32
cost
;
if
(
hashlimit_init_dst
(
hinfo
,
&
dst
,
skb
,
par
->
thoff
)
<
0
)
goto
hotdrop
;
...
...
@@ -532,21 +600,21 @@ hashlimit_mt(const struct sk_buff *skb, struct xt_action_param *par)
goto
hotdrop
;
}
dh
->
expires
=
jiffies
+
msecs_to_jiffies
(
hinfo
->
cfg
.
expire
);
dh
->
rateinfo
.
prev
=
jiffies
;
dh
->
rateinfo
.
credit
=
user2credits
(
hinfo
->
cfg
.
avg
*
hinfo
->
cfg
.
burst
);
dh
->
rateinfo
.
credit_cap
=
user2credits
(
hinfo
->
cfg
.
avg
*
hinfo
->
cfg
.
burst
);
dh
->
rateinfo
.
cost
=
user2credits
(
hinfo
->
cfg
.
avg
);
rateinfo_init
(
dh
,
hinfo
);
}
else
{
/* update expiration timeout */
dh
->
expires
=
now
+
msecs_to_jiffies
(
hinfo
->
cfg
.
expire
);
rateinfo_recalc
(
dh
,
now
);
rateinfo_recalc
(
dh
,
now
,
hinfo
->
cfg
.
mode
);
}
if
(
dh
->
rateinfo
.
credit
>=
dh
->
rateinfo
.
cost
)
{
if
(
info
->
cfg
.
mode
&
XT_HASHLIMIT_BYTES
)
cost
=
hashlimit_byte_cost
(
skb
->
len
,
dh
);
else
cost
=
dh
->
rateinfo
.
cost
;
if
(
dh
->
rateinfo
.
credit
>=
cost
)
{
/* below the limit */
dh
->
rateinfo
.
credit
-=
dh
->
rateinfo
.
cost
;
dh
->
rateinfo
.
credit
-=
cost
;
spin_unlock
(
&
dh
->
lock
);
rcu_read_unlock_bh
();
return
!
(
info
->
cfg
.
mode
&
XT_HASHLIMIT_INVERT
);
...
...
@@ -568,14 +636,6 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par)
struct
xt_hashlimit_mtinfo1
*
info
=
par
->
matchinfo
;
int
ret
;
/* Check for overflow. */
if
(
info
->
cfg
.
burst
==
0
||
user2credits
(
info
->
cfg
.
avg
*
info
->
cfg
.
burst
)
<
user2credits
(
info
->
cfg
.
avg
))
{
pr_info
(
"overflow, try lower: %u/%u
\n
"
,
info
->
cfg
.
avg
,
info
->
cfg
.
burst
);
return
-
ERANGE
;
}
if
(
info
->
cfg
.
gc_interval
==
0
||
info
->
cfg
.
expire
==
0
)
return
-
EINVAL
;
if
(
info
->
name
[
sizeof
(
info
->
name
)
-
1
]
!=
'\0'
)
...
...
@@ -588,6 +648,26 @@ static int hashlimit_mt_check(const struct xt_mtchk_param *par)
return
-
EINVAL
;
}
if
(
info
->
cfg
.
mode
>=
XT_HASHLIMIT_MAX
)
{
pr_info
(
"Unknown mode mask %X, kernel too old?
\n
"
,
info
->
cfg
.
mode
);
return
-
EINVAL
;
}
/* Check for overflow. */
if
(
info
->
cfg
.
mode
&
XT_HASHLIMIT_BYTES
)
{
if
(
user2credits_byte
(
info
->
cfg
.
avg
)
==
0
)
{
pr_info
(
"overflow, rate too high: %u
\n
"
,
info
->
cfg
.
avg
);
return
-
EINVAL
;
}
}
else
if
(
info
->
cfg
.
burst
==
0
||
user2credits
(
info
->
cfg
.
avg
*
info
->
cfg
.
burst
)
<
user2credits
(
info
->
cfg
.
avg
))
{
pr_info
(
"overflow, try lower: %u/%u
\n
"
,
info
->
cfg
.
avg
,
info
->
cfg
.
burst
);
return
-
ERANGE
;
}
mutex_lock
(
&
hashlimit_mutex
);
info
->
hinfo
=
htable_find_get
(
net
,
info
->
name
,
par
->
family
);
if
(
info
->
hinfo
==
NULL
)
{
...
...
@@ -680,10 +760,11 @@ static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
struct
seq_file
*
s
)
{
int
res
;
const
struct
xt_hashlimit_htable
*
ht
=
s
->
private
;
spin_lock
(
&
ent
->
lock
);
/* recalculate to show accurate numbers */
rateinfo_recalc
(
ent
,
jiffies
);
rateinfo_recalc
(
ent
,
jiffies
,
ht
->
cfg
.
mode
);
switch
(
family
)
{
case
NFPROTO_IPV4
:
...
...
This diff is collapsed.
Click to expand it.
net/netfilter/xt_limit.c
浏览文件 @
a49d1a90
...
...
@@ -88,8 +88,7 @@ limit_mt(const struct sk_buff *skb, struct xt_action_param *par)
}
/* Precision saver. */
static
u_int32_t
user2credits
(
u_int32_t
user
)
static
u32
user2credits
(
u32
user
)
{
/* If multiplying would overflow... */
if
(
user
>
0xFFFFFFFF
/
(
HZ
*
CREDITS_PER_JIFFY
))
...
...
@@ -123,7 +122,7 @@ static int limit_mt_check(const struct xt_mtchk_param *par)
128. */
priv
->
prev
=
jiffies
;
priv
->
credit
=
user2credits
(
r
->
avg
*
r
->
burst
);
/* Credits full. */
r
->
credit_cap
=
user2credits
(
r
->
avg
*
r
->
burst
)
;
/* Credits full. */
r
->
credit_cap
=
priv
->
credit
;
/* Credits full. */
r
->
cost
=
user2credits
(
r
->
avg
);
}
return
0
;
...
...
This diff is collapsed.
Click to expand it.
net/netfilter/xt_socket.c
浏览文件 @
a49d1a90
...
...
@@ -263,10 +263,10 @@ socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par)
struct
sock
*
sk
;
struct
in6_addr
*
daddr
,
*
saddr
;
__be16
dport
,
sport
;
int
thoff
,
tproto
;
int
thoff
=
0
,
tproto
;
const
struct
xt_socket_mtinfo1
*
info
=
(
struct
xt_socket_mtinfo1
*
)
par
->
matchinfo
;
tproto
=
ipv6_find_hdr
(
skb
,
&
thoff
,
-
1
,
NULL
);
tproto
=
ipv6_find_hdr
(
skb
,
&
thoff
,
-
1
,
NULL
,
NULL
);
if
(
tproto
<
0
)
{
pr_debug
(
"unable to find transport header in IPv6 packet, dropping
\n
"
);
return
NF_DROP
;
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录
反馈
建议
客服
返回
顶部