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
0aa30dc6
Commit
0aa30dc6
authored
Oct 27, 2002
by
Bart De Schuymer
Committed by
David S. Miller
Oct 27, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[BRIDGE]: bridge-nf, map IPv4 hooks onto bridge hooks.
parent
500ae766
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
771 additions
and
15 deletions
+771
-15
include/linux/netfilter.h
include/linux/netfilter.h
+9
-3
include/linux/netfilter_bridge.h
include/linux/netfilter_bridge.h
+28
-2
include/linux/netfilter_ipv4.h
include/linux/netfilter_ipv4.h
+2
-0
include/linux/skbuff.h
include/linux/skbuff.h
+29
-0
net/bridge/Makefile
net/bridge/Makefile
+5
-0
net/bridge/br.c
net/bridge/br.c
+7
-0
net/bridge/br_forward.c
net/bridge/br_forward.c
+10
-5
net/bridge/br_input.c
net/bridge/br_input.c
+1
-1
net/bridge/br_netfilter.c
net/bridge/br_netfilter.c
+614
-0
net/bridge/br_private.h
net/bridge/br_private.h
+7
-0
net/core/netfilter.c
net/core/netfilter.c
+27
-4
net/core/skbuff.c
net/core/skbuff.c
+16
-0
net/ipv4/ip_output.c
net/ipv4/ip_output.c
+4
-0
net/ipv4/netfilter/ipt_LOG.c
net/ipv4/netfilter/ipt_LOG.c
+12
-0
No files found.
include/linux/netfilter.h
View file @
0aa30dc6
...
...
@@ -117,17 +117,23 @@ extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
/* This is gross, but inline doesn't cut it for avoiding the function
call in fast path: gcc doesn't inline (needs value tracking?). --RR */
#ifdef CONFIG_NETFILTER_DEBUG
#define NF_HOOK nf_hook_slow
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), INT_MIN)
#define NF_HOOK_THRESH nf_hook_slow
#else
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
(list_empty(&nf_hooks[(pf)][(hook)]) \
? (okfn)(skb) \
: nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn)))
: nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), INT_MIN))
#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \
(list_empty(&nf_hooks[(pf)][(hook)]) \
? (okfn)(skb) \
: nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), (thresh)))
#endif
int
nf_hook_slow
(
int
pf
,
unsigned
int
hook
,
struct
sk_buff
*
skb
,
struct
net_device
*
indev
,
struct
net_device
*
outdev
,
int
(
*
okfn
)(
struct
sk_buff
*
));
int
(
*
okfn
)(
struct
sk_buff
*
)
,
int
thresh
);
/* Call setsockopt() */
int
nf_setsockopt
(
struct
sock
*
sk
,
int
pf
,
int
optval
,
char
*
opt
,
...
...
include/linux/netfilter_bridge.h
View file @
0aa30dc6
...
...
@@ -6,6 +6,7 @@
#include <linux/config.h>
#include <linux/netfilter.h>
#include <asm/atomic.h>
/* Bridge Hooks */
/* After promisc drops, checksum checks. */
...
...
@@ -22,14 +23,39 @@
#define NF_BR_BROUTING 5
#define NF_BR_NUMHOOKS 6
#define BRNF_PKT_TYPE 0x01
#define BRNF_BRIDGED_DNAT 0x02
#define BRNF_DONT_TAKE_PARENT 0x04
enum
nf_br_hook_priorities
{
NF_BR_PRI_FIRST
=
INT_MIN
,
NF_BR_PRI_FILTER_BRIDGED
=
-
200
,
NF_BR_PRI_FILTER_OTHER
=
200
,
NF_BR_PRI_NAT_DST_BRIDGED
=
-
300
,
NF_BR_PRI_FILTER_BRIDGED
=
-
200
,
NF_BR_PRI_BRNF
=
0
,
NF_BR_PRI_NAT_DST_OTHER
=
100
,
NF_BR_PRI_FILTER_OTHER
=
200
,
NF_BR_PRI_NAT_SRC
=
300
,
NF_BR_PRI_LAST
=
INT_MAX
,
};
static
inline
struct
nf_bridge_info
*
nf_bridge_alloc
(
struct
sk_buff
*
skb
)
{
struct
nf_bridge_info
**
nf_bridge
=
&
(
skb
->
nf_bridge
);
if
((
*
nf_bridge
=
kmalloc
(
sizeof
(
**
nf_bridge
),
GFP_ATOMIC
))
!=
NULL
)
{
atomic_set
(
&
(
*
nf_bridge
)
->
use
,
1
);
(
*
nf_bridge
)
->
mask
=
0
;
(
*
nf_bridge
)
->
physindev
=
(
*
nf_bridge
)
->
physoutdev
=
NULL
;
}
return
*
nf_bridge
;
}
struct
bridge_skb_cb
{
union
{
__u32
ipv4
;
}
daddr
;
};
#endif
include/linux/netfilter_ipv4.h
View file @
0aa30dc6
...
...
@@ -52,8 +52,10 @@
enum
nf_ip_hook_priorities
{
NF_IP_PRI_FIRST
=
INT_MIN
,
NF_IP_PRI_CONNTRACK
=
-
200
,
NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD
=
-
175
,
NF_IP_PRI_MANGLE
=
-
150
,
NF_IP_PRI_NAT_DST
=
-
100
,
NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT
=
-
50
,
NF_IP_PRI_FILTER
=
0
,
NF_IP_PRI_NAT_SRC
=
100
,
NF_IP_PRI_LAST
=
INT_MAX
,
...
...
include/linux/skbuff.h
View file @
0aa30dc6
...
...
@@ -96,6 +96,17 @@ struct nf_conntrack {
struct
nf_ct_info
{
struct
nf_conntrack
*
master
;
};
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
struct
nf_bridge_info
{
atomic_t
use
;
struct
net_device
*
physindev
;
struct
net_device
*
physoutdev
;
unsigned
int
mask
;
unsigned
long
hh
[
16
/
sizeof
(
unsigned
long
)];
};
#endif
#endif
struct
sk_buff_head
{
...
...
@@ -166,6 +177,7 @@ struct skb_shared_info {
* @nfcache: Cache info
* @nfct: Associated connection, if any
* @nf_debug: Netfilter debugging
* @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
* @tc_index: Traffic control index
*/
...
...
@@ -236,6 +248,9 @@ struct sk_buff {
#ifdef CONFIG_NETFILTER_DEBUG
unsigned
int
nf_debug
;
#endif
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
struct
nf_bridge_info
*
nf_bridge
;
#endif
#endif
/* CONFIG_NETFILTER */
#if defined(CONFIG_HIPPI)
union
{
...
...
@@ -1146,6 +1161,20 @@ static inline void nf_conntrack_get(struct nf_ct_info *nfct)
if
(
nfct
)
atomic_inc
(
&
nfct
->
master
->
use
);
}
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
static
inline
void
nf_bridge_put
(
struct
nf_bridge_info
*
nf_bridge
)
{
if
(
nf_bridge
&&
atomic_dec_and_test
(
&
nf_bridge
->
use
))
kfree
(
nf_bridge
);
}
static
inline
void
nf_bridge_get
(
struct
nf_bridge_info
*
nf_bridge
)
{
if
(
nf_bridge
)
atomic_inc
(
&
nf_bridge
->
use
);
}
#endif
#endif
#endif
/* __KERNEL__ */
...
...
net/bridge/Makefile
View file @
0aa30dc6
...
...
@@ -9,6 +9,11 @@ obj-$(CONFIG_BRIDGE) += bridge.o
bridge-objs
:=
br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o
\
br_ioctl.o br_notify.o br_stp.o br_stp_bpdu.o
\
br_stp_if.o br_stp_timer.o
ifeq
($(CONFIG_NETFILTER),y)
bridge-objs
+=
br_netfilter.o
endif
obj-$(CONFIG_BRIDGE_NF_EBTABLES)
+=
netfilter/
include
$(TOPDIR)/Rules.make
net/bridge/br.c
View file @
0aa30dc6
...
...
@@ -45,6 +45,10 @@ static int __init br_init(void)
{
printk
(
KERN_INFO
"NET4: Ethernet Bridge 008 for NET4.0
\n
"
);
#ifdef CONFIG_NETFILTER
if
(
br_netfilter_init
())
return
1
;
#endif
br_handle_frame_hook
=
br_handle_frame
;
br_ioctl_hook
=
br_ioctl_deviceless_stub
;
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
...
...
@@ -63,6 +67,9 @@ static void __br_clear_ioctl_hook(void)
static
void
__exit
br_deinit
(
void
)
{
#ifdef CONFIG_NETFILTER
br_netfilter_fini
();
#endif
unregister_netdevice_notifier
(
&
br_device_notifier
);
br_call_ioctl_atomic
(
__br_clear_ioctl_hook
);
...
...
net/bridge/br_forward.c
View file @
0aa30dc6
...
...
@@ -30,18 +30,23 @@ static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb)
return
1
;
}
static
int
_
_dev_queue_push_xmit
(
struct
sk_buff
*
skb
)
int
br
_dev_queue_push_xmit
(
struct
sk_buff
*
skb
)
{
#ifdef CONFIG_NETFILTER
if
(
skb
->
nf_bridge
)
memcpy
(
skb
->
data
-
16
,
skb
->
nf_bridge
->
hh
,
16
);
#endif
skb_push
(
skb
,
ETH_HLEN
);
dev_queue_xmit
(
skb
);
return
0
;
}
static
int
__
br_forward_finish
(
struct
sk_buff
*
skb
)
int
br_forward_finish
(
struct
sk_buff
*
skb
)
{
NF_HOOK
(
PF_BRIDGE
,
NF_BR_POST_ROUTING
,
skb
,
NULL
,
skb
->
dev
,
_
_dev_queue_push_xmit
);
br
_dev_queue_push_xmit
);
return
0
;
}
...
...
@@ -53,7 +58,7 @@ static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb)
skb
->
nf_debug
=
0
;
#endif
NF_HOOK
(
PF_BRIDGE
,
NF_BR_LOCAL_OUT
,
skb
,
NULL
,
skb
->
dev
,
__
br_forward_finish
);
br_forward_finish
);
}
static
void
__br_forward
(
struct
net_bridge_port
*
to
,
struct
sk_buff
*
skb
)
...
...
@@ -64,7 +69,7 @@ static void __br_forward(struct net_bridge_port *to, struct sk_buff *skb)
skb
->
dev
=
to
->
dev
;
NF_HOOK
(
PF_BRIDGE
,
NF_BR_FORWARD
,
skb
,
indev
,
skb
->
dev
,
__
br_forward_finish
);
br_forward_finish
);
}
/* called under bridge lock */
...
...
net/bridge/br_input.c
View file @
0aa30dc6
...
...
@@ -49,7 +49,7 @@ static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
br_pass_frame_up_finish
);
}
static
int
br_handle_frame_finish
(
struct
sk_buff
*
skb
)
int
br_handle_frame_finish
(
struct
sk_buff
*
skb
)
{
struct
net_bridge
*
br
;
unsigned
char
*
dest
;
...
...
net/bridge/br_netfilter.c
0 → 100644
View file @
0aa30dc6
This diff is collapsed.
Click to expand it.
net/bridge/br_private.h
View file @
0aa30dc6
...
...
@@ -144,8 +144,10 @@ extern void br_fdb_insert(struct net_bridge *br,
/* br_forward.c */
extern
void
br_deliver
(
struct
net_bridge_port
*
to
,
struct
sk_buff
*
skb
);
extern
int
br_dev_queue_push_xmit
(
struct
sk_buff
*
skb
);
extern
void
br_forward
(
struct
net_bridge_port
*
to
,
struct
sk_buff
*
skb
);
extern
int
br_forward_finish
(
struct
sk_buff
*
skb
);
extern
void
br_flood_deliver
(
struct
net_bridge
*
br
,
struct
sk_buff
*
skb
,
int
clone
);
...
...
@@ -166,6 +168,7 @@ extern void br_get_port_ifindices(struct net_bridge *br,
int
*
ifindices
);
/* br_input.c */
extern
int
br_handle_frame_finish
(
struct
sk_buff
*
skb
);
extern
int
br_handle_frame
(
struct
sk_buff
*
skb
);
/* br_ioctl.c */
...
...
@@ -177,6 +180,10 @@ extern int br_ioctl(struct net_bridge *br,
unsigned
long
arg2
);
extern
int
br_ioctl_deviceless_stub
(
unsigned
long
arg
);
/* br_netfilter.c */
extern
int
br_netfilter_init
(
void
);
extern
void
br_netfilter_fini
(
void
);
/* br_stp.c */
extern
int
br_is_root_bridge
(
struct
net_bridge
*
br
);
extern
struct
net_bridge_port
*
br_get_port
(
struct
net_bridge
*
br
,
...
...
net/core/netfilter.c
View file @
0aa30dc6
...
...
@@ -342,10 +342,15 @@ static unsigned int nf_iterate(struct list_head *head,
const
struct
net_device
*
indev
,
const
struct
net_device
*
outdev
,
struct
list_head
**
i
,
int
(
*
okfn
)(
struct
sk_buff
*
))
int
(
*
okfn
)(
struct
sk_buff
*
),
int
hook_thresh
)
{
for
(
*
i
=
(
*
i
)
->
next
;
*
i
!=
head
;
*
i
=
(
*
i
)
->
next
)
{
struct
nf_hook_ops
*
elem
=
(
struct
nf_hook_ops
*
)
*
i
;
if
(
hook_thresh
>
elem
->
priority
)
continue
;
switch
(
elem
->
hook
(
hook
,
skb
,
indev
,
outdev
,
okfn
))
{
case
NF_QUEUE
:
return
NF_QUEUE
;
...
...
@@ -413,6 +418,10 @@ static void nf_queue(struct sk_buff *skb,
{
int
status
;
struct
nf_info
*
info
;
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
struct
net_device
*
physindev
=
NULL
;
struct
net_device
*
physoutdev
=
NULL
;
#endif
if
(
!
queue_handler
[
pf
].
outfn
)
{
kfree_skb
(
skb
);
...
...
@@ -435,11 +444,24 @@ static void nf_queue(struct sk_buff *skb,
if
(
indev
)
dev_hold
(
indev
);
if
(
outdev
)
dev_hold
(
outdev
);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
if
(
skb
->
nf_bridge
)
{
physindev
=
skb
->
nf_bridge
->
physindev
;
if
(
physindev
)
dev_hold
(
physindev
);
physoutdev
=
skb
->
nf_bridge
->
physoutdev
;
if
(
physoutdev
)
dev_hold
(
physoutdev
);
}
#endif
status
=
queue_handler
[
pf
].
outfn
(
skb
,
info
,
queue_handler
[
pf
].
data
);
if
(
status
<
0
)
{
/* James M doesn't say fuck enough. */
if
(
indev
)
dev_put
(
indev
);
if
(
outdev
)
dev_put
(
outdev
);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
if
(
physindev
)
dev_put
(
physindev
);
if
(
physoutdev
)
dev_put
(
physoutdev
);
#endif
kfree
(
info
);
kfree_skb
(
skb
);
return
;
...
...
@@ -449,7 +471,8 @@ static void nf_queue(struct sk_buff *skb,
int
nf_hook_slow
(
int
pf
,
unsigned
int
hook
,
struct
sk_buff
*
skb
,
struct
net_device
*
indev
,
struct
net_device
*
outdev
,
int
(
*
okfn
)(
struct
sk_buff
*
))
int
(
*
okfn
)(
struct
sk_buff
*
),
int
hook_thresh
)
{
struct
list_head
*
elem
;
unsigned
int
verdict
;
...
...
@@ -481,7 +504,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
elem
=
&
nf_hooks
[
pf
][
hook
];
verdict
=
nf_iterate
(
&
nf_hooks
[
pf
][
hook
],
&
skb
,
hook
,
indev
,
outdev
,
&
elem
,
okfn
);
outdev
,
&
elem
,
okfn
,
hook_thresh
);
if
(
verdict
==
NF_QUEUE
)
{
NFDEBUG
(
"nf_hook: Verdict = QUEUE.
\n
"
);
nf_queue
(
skb
,
elem
,
pf
,
hook
,
indev
,
outdev
,
okfn
);
...
...
@@ -530,7 +553,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
verdict
=
nf_iterate
(
&
nf_hooks
[
info
->
pf
][
info
->
hook
],
&
skb
,
info
->
hook
,
info
->
indev
,
info
->
outdev
,
&
elem
,
info
->
okfn
);
info
->
okfn
,
INT_MIN
);
}
switch
(
verdict
)
{
...
...
net/core/skbuff.c
View file @
0aa30dc6
...
...
@@ -248,6 +248,9 @@ static inline void skb_headerinit(void *p, kmem_cache_t *cache,
#ifdef CONFIG_NETFILTER_DEBUG
skb
->
nf_debug
=
0
;
#endif
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
skb
->
nf_bridge
=
NULL
;
#endif
#endif
#ifdef CONFIG_NET_SCHED
skb
->
tc_index
=
0
;
...
...
@@ -327,6 +330,9 @@ void __kfree_skb(struct sk_buff *skb)
}
#ifdef CONFIG_NETFILTER
nf_conntrack_put
(
skb
->
nfct
);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
nf_bridge_put
(
skb
->
nf_bridge
);
#endif
#endif
skb_headerinit
(
skb
,
NULL
,
0
);
/* clean state */
kfree_skbmem
(
skb
);
...
...
@@ -392,6 +398,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
#ifdef CONFIG_NETFILTER_DEBUG
C
(
nf_debug
);
#endif
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
C
(
nf_bridge
);
#endif
#endif
/*CONFIG_NETFILTER*/
#if defined(CONFIG_HIPPI)
C
(
private
);
...
...
@@ -404,6 +413,9 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
skb
->
cloned
=
1
;
#ifdef CONFIG_NETFILTER
nf_conntrack_get
(
skb
->
nfct
);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
nf_bridge_get
(
skb
->
nf_bridge
);
#endif
#endif
return
n
;
}
...
...
@@ -438,6 +450,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
#ifdef CONFIG_NETFILTER_DEBUG
new
->
nf_debug
=
old
->
nf_debug
;
#endif
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
new
->
nf_bridge
=
old
->
nf_bridge
;
nf_bridge_get
(
new
->
nf_bridge
);
#endif
#endif
#ifdef CONFIG_NET_SCHED
new
->
tc_index
=
old
->
tc_index
;
...
...
net/ipv4/ip_output.c
View file @
0aa30dc6
...
...
@@ -402,6 +402,10 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
/* Connection association is same as pre-frag packet */
to
->
nfct
=
from
->
nfct
;
nf_conntrack_get
(
to
->
nfct
);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
to
->
nf_bridge
=
from
->
nf_bridge
;
nf_bridge_get
(
to
->
nf_bridge
);
#endif
#ifdef CONFIG_NETFILTER_DEBUG
to
->
nf_debug
=
from
->
nf_debug
;
#endif
...
...
net/ipv4/netfilter/ipt_LOG.c
View file @
0aa30dc6
...
...
@@ -289,6 +289,18 @@ ipt_log_target(struct sk_buff **pskb,
loginfo
->
prefix
,
in
?
in
->
name
:
""
,
out
?
out
->
name
:
""
);
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
if
((
*
pskb
)
->
nf_bridge
)
{
struct
net_device
*
physindev
=
(
*
pskb
)
->
nf_bridge
->
physindev
;
struct
net_device
*
physoutdev
=
(
*
pskb
)
->
nf_bridge
->
physoutdev
;
if
(
physindev
&&
in
!=
physindev
)
printk
(
"PHYSIN=%s "
,
physindev
->
name
);
if
(
physoutdev
&&
out
!=
physoutdev
)
printk
(
"PHYSOUT=%s "
,
physoutdev
->
name
);
}
#endif
if
(
in
&&
!
out
)
{
/* MAC logging for input chain only. */
printk
(
"MAC="
);
...
...
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