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
fdce75b3
Commit
fdce75b3
authored
Nov 23, 2004
by
David S. Miller
Browse files
Options
Browse Files
Download
Plain Diff
Merge davem@nuts.davemloft.net:/disk1/BK/net-2.6.11
into kernel.bkbits.net:/home/davem/net-2.6.11
parents
025fd9de
6d141d44
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
633 additions
and
247 deletions
+633
-247
drivers/net/Makefile
drivers/net/Makefile
+1
-1
drivers/net/net_init.c
drivers/net/net_init.c
+0
-152
include/linux/netfilter_bridge/ebt_ulog.h
include/linux/netfilter_bridge/ebt_ulog.h
+36
-0
include/linux/netfilter_bridge/ebtables.h
include/linux/netfilter_bridge/ebtables.h
+3
-3
include/linux/pkt_cls.h
include/linux/pkt_cls.h
+1
-0
include/linux/skbuff.h
include/linux/skbuff.h
+6
-0
include/net/act_api.h
include/net/act_api.h
+2
-2
include/net/pkt_cls.h
include/net/pkt_cls.h
+6
-20
net/bridge/netfilter/Kconfig
net/bridge/netfilter/Kconfig
+16
-2
net/bridge/netfilter/Makefile
net/bridge/netfilter/Makefile
+1
-0
net/bridge/netfilter/ebt_log.c
net/bridge/netfilter/ebt_log.c
+3
-2
net/bridge/netfilter/ebt_ulog.c
net/bridge/netfilter/ebt_ulog.c
+295
-0
net/bridge/netfilter/ebtables.c
net/bridge/netfilter/ebtables.c
+3
-3
net/core/dev.c
net/core/dev.c
+109
-5
net/core/skbuff.c
net/core/skbuff.c
+53
-0
net/sched/Kconfig
net/sched/Kconfig
+12
-0
net/sched/act_api.c
net/sched/act_api.c
+47
-57
net/sched/cls_u32.c
net/sched/cls_u32.c
+39
-0
No files found.
drivers/net/Makefile
View file @
fdce75b3
...
@@ -66,7 +66,7 @@ obj-$(CONFIG_MII) += mii.o
...
@@ -66,7 +66,7 @@ obj-$(CONFIG_MII) += mii.o
obj-$(CONFIG_SUNDANCE)
+=
sundance.o
obj-$(CONFIG_SUNDANCE)
+=
sundance.o
obj-$(CONFIG_HAMACHI)
+=
hamachi.o
obj-$(CONFIG_HAMACHI)
+=
hamachi.o
obj-$(CONFIG_NET)
+=
Space.o
net_init.o
loopback.o
obj-$(CONFIG_NET)
+=
Space.o loopback.o
obj-$(CONFIG_SEEQ8005)
+=
seeq8005.o
obj-$(CONFIG_SEEQ8005)
+=
seeq8005.o
obj-$(CONFIG_ETHERTAP)
+=
ethertap.o
obj-$(CONFIG_ETHERTAP)
+=
ethertap.o
obj-$(CONFIG_NET_SB1000)
+=
sb1000.o
obj-$(CONFIG_NET_SB1000)
+=
sb1000.o
...
...
drivers/net/net_init.c
deleted
100644 → 0
View file @
025fd9de
/* net_init.c: Initialization for network devices. */
/*
Written 1993,1994,1995 by Donald Becker.
The author may be reached as becker@scyld.com, or C/O
Scyld Computing Corporation
410 Severn Ave., Suite 210
Annapolis MD 21403
This file contains the initialization for the "pl14+" style ethernet
drivers. It should eventually replace most of drivers/net/Space.c.
It's primary advantage is that it's able to allocate low-memory buffers.
A secondary advantage is that the dangerous NE*000 netcards can reserve
their I/O port region before the SCSI probes start.
Modifications/additions by Bjorn Ekwall <bj0rn@blox.se>:
ethdev_index[MAX_ETH_CARDS]
register_netdev() / unregister_netdev()
Modifications by Wolfgang Walter
Use dev_close cleanly so we always shut things down tidily.
Changed 29/10/95, Alan Cox to pass sockaddr's around for mac addresses.
14/06/96 - Paul Gortmaker: Add generic eth_change_mtu() function.
24/09/96 - Paul Norton: Add token-ring variants of the netdev functions.
08/11/99 - Alan Cox: Got fed up of the mess in this file and cleaned it
up. We now share common code and have regularised name
allocation setups. Abolished the 16 card limits.
03/19/2000 - jgarzik and Urban Widmark: init_etherdev 32-byte align
03/21/2001 - jgarzik: alloc_etherdev and friends
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/if_ether.h>
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/fddidevice.h>
#include <linux/hippidevice.h>
#include <linux/trdevice.h>
#include <linux/fcdevice.h>
#include <linux/if_arp.h>
#include <linux/if_ltalk.h>
#include <linux/rtnetlink.h>
#include <net/neighbour.h>
/* The network devices currently exist only in the socket namespace, so these
entries are unused. The only ones that make sense are
open start the ethercard
close stop the ethercard
ioctl To get statistics, perhaps set the interface port (AUI, BNC, etc.)
One can also imagine getting raw packets using
read & write
but this is probably better handled by a raw packet socket.
Given that almost all of these functions are handled in the current
socket-based scheme, putting ethercard devices in /dev/ seems pointless.
[Removed all support for /dev network devices. When someone adds
streams then by magic we get them, but otherwise they are un-needed
and a space waste]
*/
struct
net_device
*
alloc_netdev
(
int
sizeof_priv
,
const
char
*
mask
,
void
(
*
setup
)(
struct
net_device
*
))
{
void
*
p
;
struct
net_device
*
dev
;
int
alloc_size
;
/* ensure 32-byte alignment of both the device and private area */
alloc_size
=
(
sizeof
(
struct
net_device
)
+
NETDEV_ALIGN_CONST
)
&
~
NETDEV_ALIGN_CONST
;
alloc_size
+=
sizeof_priv
+
NETDEV_ALIGN_CONST
;
p
=
kmalloc
(
alloc_size
,
GFP_KERNEL
);
if
(
!
p
)
{
printk
(
KERN_ERR
"alloc_dev: Unable to allocate device.
\n
"
);
return
NULL
;
}
memset
(
p
,
0
,
alloc_size
);
dev
=
(
struct
net_device
*
)(((
long
)
p
+
NETDEV_ALIGN_CONST
)
&
~
NETDEV_ALIGN_CONST
);
dev
->
padded
=
(
char
*
)
dev
-
(
char
*
)
p
;
if
(
sizeof_priv
)
dev
->
priv
=
netdev_priv
(
dev
);
setup
(
dev
);
strcpy
(
dev
->
name
,
mask
);
return
dev
;
}
EXPORT_SYMBOL
(
alloc_netdev
);
int
register_netdev
(
struct
net_device
*
dev
)
{
int
err
;
rtnl_lock
();
/*
* If the name is a format string the caller wants us to
* do a name allocation
*/
if
(
strchr
(
dev
->
name
,
'%'
))
{
err
=
dev_alloc_name
(
dev
,
dev
->
name
);
if
(
err
<
0
)
goto
out
;
}
/*
* Back compatibility hook. Kill this one in 2.5
*/
if
(
dev
->
name
[
0
]
==
0
||
dev
->
name
[
0
]
==
' '
)
{
err
=
dev_alloc_name
(
dev
,
"eth%d"
);
if
(
err
<
0
)
goto
out
;
}
err
=
register_netdevice
(
dev
);
out:
rtnl_unlock
();
return
err
;
}
void
unregister_netdev
(
struct
net_device
*
dev
)
{
rtnl_lock
();
unregister_netdevice
(
dev
);
rtnl_unlock
();
}
EXPORT_SYMBOL
(
register_netdev
);
EXPORT_SYMBOL
(
unregister_netdev
);
include/linux/netfilter_bridge/ebt_ulog.h
0 → 100644
View file @
fdce75b3
#ifndef _EBT_ULOG_H
#define _EBT_ULOG_H
#define EBT_ULOG_DEFAULT_NLGROUP 0
#define EBT_ULOG_DEFAULT_QTHRESHOLD 1
#define EBT_ULOG_MAXNLGROUPS 32
/* hardcoded netlink max */
#define EBT_ULOG_PREFIX_LEN 32
#define EBT_ULOG_MAX_QLEN 50
#define EBT_ULOG_WATCHER "ulog"
#define EBT_ULOG_VERSION 1
struct
ebt_ulog_info
{
uint32_t
nlgroup
;
unsigned
int
cprange
;
unsigned
int
qthreshold
;
char
prefix
[
EBT_ULOG_PREFIX_LEN
];
};
typedef
struct
ebt_ulog_packet_msg
{
int
version
;
char
indev
[
IFNAMSIZ
];
char
outdev
[
IFNAMSIZ
];
char
physindev
[
IFNAMSIZ
];
char
physoutdev
[
IFNAMSIZ
];
char
prefix
[
EBT_ULOG_PREFIX_LEN
];
struct
timeval
stamp
;
unsigned
long
mark
;
unsigned
int
hook
;
size_t
data_len
;
/* The complete packet, including Ethernet header and perhaps
* the VLAN header is appended */
unsigned
char
data
[
0
]
__attribute__
((
aligned
(
__alignof__
(
struct
ebt_ulog_info
))));
}
ebt_ulog_packet_msg_t
;
#endif
/* _EBT_ULOG_H */
include/linux/netfilter_bridge/ebtables.h
View file @
fdce75b3
...
@@ -201,9 +201,9 @@ struct ebt_watcher
...
@@ -201,9 +201,9 @@ struct ebt_watcher
{
{
struct
list_head
list
;
struct
list_head
list
;
const
char
name
[
EBT_FUNCTION_MAXNAMELEN
];
const
char
name
[
EBT_FUNCTION_MAXNAMELEN
];
void
(
*
watcher
)(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
void
(
*
watcher
)(
const
struct
sk_buff
*
skb
,
unsigned
int
hooknr
,
const
struct
net_device
*
out
,
const
void
*
watcherdata
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
unsigned
int
datalen
);
const
void
*
watcherdata
,
unsigned
int
datalen
);
/* 0 == let it in */
/* 0 == let it in */
int
(
*
check
)(
const
char
*
tablename
,
unsigned
int
hookmask
,
int
(
*
check
)(
const
char
*
tablename
,
unsigned
int
hookmask
,
const
struct
ebt_entry
*
e
,
void
*
watcherdata
,
unsigned
int
datalen
);
const
struct
ebt_entry
*
e
,
void
*
watcherdata
,
unsigned
int
datalen
);
...
...
include/linux/pkt_cls.h
View file @
fdce75b3
...
@@ -192,6 +192,7 @@ enum
...
@@ -192,6 +192,7 @@ enum
TCA_U32_ACT
,
TCA_U32_ACT
,
TCA_U32_INDEV
,
TCA_U32_INDEV
,
TCA_U32_PCNT
,
TCA_U32_PCNT
,
TCA_U32_MARK
,
__TCA_U32_MAX
__TCA_U32_MAX
};
};
...
...
include/linux/skbuff.h
View file @
fdce75b3
...
@@ -292,6 +292,8 @@ struct sk_buff {
...
@@ -292,6 +292,8 @@ struct sk_buff {
extern
void
__kfree_skb
(
struct
sk_buff
*
skb
);
extern
void
__kfree_skb
(
struct
sk_buff
*
skb
);
extern
struct
sk_buff
*
alloc_skb
(
unsigned
int
size
,
int
priority
);
extern
struct
sk_buff
*
alloc_skb
(
unsigned
int
size
,
int
priority
);
extern
struct
sk_buff
*
alloc_skb_from_cache
(
kmem_cache_t
*
cp
,
unsigned
int
size
,
int
priority
);
extern
void
kfree_skbmem
(
struct
sk_buff
*
skb
);
extern
void
kfree_skbmem
(
struct
sk_buff
*
skb
);
extern
struct
sk_buff
*
skb_clone
(
struct
sk_buff
*
skb
,
int
priority
);
extern
struct
sk_buff
*
skb_clone
(
struct
sk_buff
*
skb
,
int
priority
);
extern
struct
sk_buff
*
skb_copy
(
const
struct
sk_buff
*
skb
,
int
priority
);
extern
struct
sk_buff
*
skb_copy
(
const
struct
sk_buff
*
skb
,
int
priority
);
...
@@ -935,6 +937,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
...
@@ -935,6 +937,7 @@ static inline void __skb_queue_purge(struct sk_buff_head *list)
*
*
* %NULL is returned in there is no free memory.
* %NULL is returned in there is no free memory.
*/
*/
#ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB
static
inline
struct
sk_buff
*
__dev_alloc_skb
(
unsigned
int
length
,
static
inline
struct
sk_buff
*
__dev_alloc_skb
(
unsigned
int
length
,
int
gfp_mask
)
int
gfp_mask
)
{
{
...
@@ -943,6 +946,9 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
...
@@ -943,6 +946,9 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length,
skb_reserve
(
skb
,
16
);
skb_reserve
(
skb
,
16
);
return
skb
;
return
skb
;
}
}
#else
extern
struct
sk_buff
*
__dev_alloc_skb
(
unsigned
int
length
,
int
gfp_mask
);
#endif
/**
/**
* dev_alloc_skb - allocate an skbuff for sending
* dev_alloc_skb - allocate an skbuff for sending
...
...
include/net/act_api.h
View file @
fdce75b3
...
@@ -87,8 +87,8 @@ extern int tcf_register_action(struct tc_action_ops *a);
...
@@ -87,8 +87,8 @@ extern int tcf_register_action(struct tc_action_ops *a);
extern
int
tcf_unregister_action
(
struct
tc_action_ops
*
a
);
extern
int
tcf_unregister_action
(
struct
tc_action_ops
*
a
);
extern
void
tcf_action_destroy
(
struct
tc_action
*
a
,
int
bind
);
extern
void
tcf_action_destroy
(
struct
tc_action
*
a
,
int
bind
);
extern
int
tcf_action_exec
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
struct
tcf_result
*
res
);
extern
int
tcf_action_exec
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
struct
tcf_result
*
res
);
extern
int
tcf_action_init
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
struct
tc_action
*
a
,
char
*
n
,
int
ovr
,
int
bind
);
extern
struct
tc_action
*
tcf_action_init
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
char
*
n
,
int
ovr
,
int
bind
,
int
*
err
);
extern
int
tcf_action_init_1
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
struct
tc_action
*
a
,
char
*
n
,
int
ovr
,
int
bind
);
extern
struct
tc_action
*
tcf_action_init_1
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
char
*
n
,
int
ovr
,
int
bind
,
int
*
err
);
extern
int
tcf_action_dump
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
int
,
int
);
extern
int
tcf_action_dump
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
int
,
int
);
extern
int
tcf_action_dump_old
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
int
,
int
);
extern
int
tcf_action_dump_old
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
int
,
int
);
extern
int
tcf_action_dump_1
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
int
,
int
);
extern
int
tcf_action_dump_1
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
,
int
,
int
);
...
...
include/net/pkt_cls.h
View file @
fdce75b3
...
@@ -70,17 +70,10 @@ tcf_change_act_police(struct tcf_proto *tp, struct tc_action **action,
...
@@ -70,17 +70,10 @@ tcf_change_act_police(struct tcf_proto *tp, struct tc_action **action,
int
ret
;
int
ret
;
struct
tc_action
*
act
;
struct
tc_action
*
act
;
act
=
kmalloc
(
sizeof
(
*
act
),
GFP_KERNEL
);
act
=
tcf_action_init_1
(
act_police_tlv
,
rate_tlv
,
"police"
,
if
(
NULL
==
act
)
TCA_ACT_NOREPLACE
,
TCA_ACT_BIND
,
&
ret
);
return
-
ENOMEM
;
if
(
act
==
NULL
)
memset
(
act
,
0
,
sizeof
(
*
act
));
ret
=
tcf_action_init_1
(
act_police_tlv
,
rate_tlv
,
act
,
"police"
,
TCA_ACT_NOREPLACE
,
TCA_ACT_BIND
);
if
(
ret
<
0
)
{
tcf_action_destroy
(
act
,
TCA_ACT_UNBIND
);
return
ret
;
return
ret
;
}
act
->
type
=
TCA_OLD_COMPAT
;
act
->
type
=
TCA_OLD_COMPAT
;
...
@@ -103,17 +96,10 @@ tcf_change_act(struct tcf_proto *tp, struct tc_action **action,
...
@@ -103,17 +96,10 @@ tcf_change_act(struct tcf_proto *tp, struct tc_action **action,
int
ret
;
int
ret
;
struct
tc_action
*
act
;
struct
tc_action
*
act
;
act
=
kmalloc
(
sizeof
(
*
act
),
GFP_KERNEL
);
act
=
tcf_action_init
(
act_tlv
,
rate_tlv
,
NULL
,
if
(
NULL
==
act
)
TCA_ACT_NOREPLACE
,
TCA_ACT_BIND
,
&
ret
);
return
-
ENOMEM
;
if
(
act
==
NULL
)
memset
(
act
,
0
,
sizeof
(
*
act
));
ret
=
tcf_action_init
(
act_tlv
,
rate_tlv
,
act
,
NULL
,
TCA_ACT_NOREPLACE
,
TCA_ACT_BIND
);
if
(
ret
<
0
)
{
tcf_action_destroy
(
act
,
TCA_ACT_UNBIND
);
return
ret
;
return
ret
;
}
if
(
*
action
)
{
if
(
*
action
)
{
tcf_tree_lock
(
tp
);
tcf_tree_lock
(
tp
);
...
...
net/bridge/netfilter/Kconfig
View file @
fdce75b3
...
@@ -189,8 +189,22 @@ config BRIDGE_EBT_LOG
...
@@ -189,8 +189,22 @@ config BRIDGE_EBT_LOG
tristate "ebt: log support"
tristate "ebt: log support"
depends on BRIDGE_NF_EBTABLES
depends on BRIDGE_NF_EBTABLES
help
help
This option adds the log target, that you can use in any rule in
This option adds the log watcher, that you can use in any rule
any ebtables table. It records the frame header to the syslog.
in any ebtables table. It records info about the frame header
to the syslog.
To compile it as a module, choose M here. If unsure, say N.
config BRIDGE_EBT_ULOG
tristate "ebt: ulog support"
depends on BRIDGE_NF_EBTABLES
help
This option adds the ulog watcher, that you can use in any rule
in any ebtables table. The packet is passed to a userspace
logging daemon using netlink multicast sockets. This differs
from the log watcher in the sense that the complete packet is
sent to userspace instead of a descriptive text and that
netlink multicast sockets are used instead of the syslog.
To compile it as a module, choose M here. If unsure, say N.
To compile it as a module, choose M here. If unsure, say N.
...
...
net/bridge/netfilter/Makefile
View file @
fdce75b3
...
@@ -29,3 +29,4 @@ obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o
...
@@ -29,3 +29,4 @@ obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o
# watchers
# watchers
obj-$(CONFIG_BRIDGE_EBT_LOG)
+=
ebt_log.o
obj-$(CONFIG_BRIDGE_EBT_LOG)
+=
ebt_log.o
obj-$(CONFIG_BRIDGE_EBT_LOG)
+=
ebt_ulog.o
net/bridge/netfilter/ebt_log.c
View file @
fdce75b3
...
@@ -55,8 +55,9 @@ static void print_MAC(unsigned char *p)
...
@@ -55,8 +55,9 @@ static void print_MAC(unsigned char *p)
}
}
#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
static
void
ebt_log
(
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
static
void
ebt_log
(
const
struct
sk_buff
*
skb
,
unsigned
int
hooknr
,
const
struct
net_device
*
out
,
const
void
*
data
,
unsigned
int
datalen
)
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
data
,
unsigned
int
datalen
)
{
{
struct
ebt_log_info
*
info
=
(
struct
ebt_log_info
*
)
data
;
struct
ebt_log_info
*
info
=
(
struct
ebt_log_info
*
)
data
;
char
level_string
[
4
]
=
"< >"
;
char
level_string
[
4
]
=
"< >"
;
...
...
net/bridge/netfilter/ebt_ulog.c
0 → 100644
View file @
fdce75b3
/*
* netfilter module for userspace bridged Ethernet frames logging daemons
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* November, 2004
*
* Based on ipt_ULOG.c, which is
* (C) 2000-2002 by Harald Welte <laforge@netfilter.org>
*
* This module accepts two parameters:
*
* nlbufsiz:
* The parameter specifies how big the buffer for each netlink multicast
* group is. e.g. If you say nlbufsiz=8192, up to eight kb of packets will
* get accumulated in the kernel until they are sent to userspace. It is
* NOT possible to allocate more than 128kB, and it is strongly discouraged,
* because atomically allocating 128kB inside the network rx softirq is not
* reliable. Please also keep in mind that this buffer size is allocated for
* each nlgroup you are using, so the total kernel memory usage increases
* by that factor.
*
* flushtimeout:
* Specify, after how many hundredths of a second the queue should be
* flushed even if it is not full yet.
*
*/
#include <linux/module.h>
#include <linux/config.h>
#include <linux/spinlock.h>
#include <linux/socket.h>
#include <linux/skbuff.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/netlink.h>
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_ulog.h>
#include <net/sock.h>
#include "../br_private.h"
#define PRINTR(format, args...) do { if (net_ratelimit()) \
printk(format , ## args); } while (0)
static
unsigned
int
nlbufsiz
=
4096
;
module_param
(
nlbufsiz
,
uint
,
0600
);
MODULE_PARM_DESC
(
nlbufsiz
,
"netlink buffer size (number of bytes) "
"(defaults to 4096)"
);
static
unsigned
int
flushtimeout
=
10
;
module_param
(
flushtimeout
,
uint
,
0600
);
MODULE_PARM_DESC
(
flushtimeout
,
"buffer flush timeout (hundredths ofa second) "
"(defaults to 10)"
);
typedef
struct
{
unsigned
int
qlen
;
/* number of nlmsgs' in the skb */
struct
nlmsghdr
*
lastnlh
;
/* netlink header of last msg in skb */
struct
sk_buff
*
skb
;
/* the pre-allocated skb */
struct
timer_list
timer
;
/* the timer function */
spinlock_t
lock
;
/* the per-queue lock */
}
ebt_ulog_buff_t
;
static
ebt_ulog_buff_t
ulog_buffers
[
EBT_ULOG_MAXNLGROUPS
];
static
struct
sock
*
ebtulognl
;
/* send one ulog_buff_t to userspace */
static
void
ulog_send
(
unsigned
int
nlgroup
)
{
ebt_ulog_buff_t
*
ub
=
&
ulog_buffers
[
nlgroup
];
if
(
timer_pending
(
&
ub
->
timer
))
del_timer
(
&
ub
->
timer
);
/* last nlmsg needs NLMSG_DONE */
if
(
ub
->
qlen
>
1
)
ub
->
lastnlh
->
nlmsg_type
=
NLMSG_DONE
;
NETLINK_CB
(
ub
->
skb
).
dst_groups
=
1
<<
nlgroup
;
netlink_broadcast
(
ebtulognl
,
ub
->
skb
,
0
,
1
<<
nlgroup
,
GFP_ATOMIC
);
ub
->
qlen
=
0
;
ub
->
skb
=
NULL
;
}
/* timer function to flush queue in flushtimeout time */
static
void
ulog_timer
(
unsigned
long
data
)
{
spin_lock_bh
(
&
ulog_buffers
[
data
].
lock
);
if
(
ulog_buffers
[
data
].
skb
)
ulog_send
(
data
);
spin_unlock_bh
(
&
ulog_buffers
[
data
].
lock
);
}
static
struct
sk_buff
*
ulog_alloc_skb
(
unsigned
int
size
)
{
struct
sk_buff
*
skb
;
skb
=
alloc_skb
(
nlbufsiz
,
GFP_ATOMIC
);
if
(
!
skb
)
{
PRINTR
(
KERN_ERR
"ebt_ulog: can't alloc whole buffer "
"of size %ub!
\n
"
,
nlbufsiz
);
if
(
size
<
nlbufsiz
)
{
/* try to allocate only as much as we need for
* current packet */
skb
=
alloc_skb
(
size
,
GFP_ATOMIC
);
if
(
!
skb
)
PRINTR
(
KERN_ERR
"ebt_ulog: can't even allocate "
"buffer of size %ub
\n
"
,
size
);
}
}
return
skb
;
}
static
void
ebt_ulog
(
const
struct
sk_buff
*
skb
,
unsigned
int
hooknr
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
,
const
void
*
data
,
unsigned
int
datalen
)
{
ebt_ulog_packet_msg_t
*
pm
;
size_t
size
,
copy_len
;
struct
nlmsghdr
*
nlh
;
struct
ebt_ulog_info
*
uloginfo
=
(
struct
ebt_ulog_info
*
)
data
;
unsigned
int
group
=
uloginfo
->
nlgroup
;
ebt_ulog_buff_t
*
ub
=
&
ulog_buffers
[
group
];
spinlock_t
*
lock
=
&
ub
->
lock
;
if
((
uloginfo
->
cprange
==
0
)
||
(
uloginfo
->
cprange
>
skb
->
len
+
ETH_HLEN
))
copy_len
=
skb
->
len
+
ETH_HLEN
;
else
copy_len
=
uloginfo
->
cprange
;
size
=
NLMSG_SPACE
(
sizeof
(
*
pm
)
+
copy_len
);
if
(
size
>
nlbufsiz
)
{
PRINTR
(
"ebt_ulog: Size %d needed, but nlbufsiz=%d
\n
"
,
size
,
nlbufsiz
);
return
;
}
spin_lock_bh
(
lock
);
if
(
!
ub
->
skb
)
{
if
(
!
(
ub
->
skb
=
ulog_alloc_skb
(
size
)))
goto
alloc_failure
;
}
else
if
(
size
>
skb_tailroom
(
ub
->
skb
))
{
ulog_send
(
group
);
if
(
!
(
ub
->
skb
=
ulog_alloc_skb
(
size
)))
goto
alloc_failure
;
}
nlh
=
NLMSG_PUT
(
ub
->
skb
,
0
,
ub
->
qlen
,
0
,
size
-
NLMSG_ALIGN
(
sizeof
(
*
nlh
)));
ub
->
qlen
++
;
pm
=
NLMSG_DATA
(
nlh
);
/* Fill in the ulog data */
pm
->
version
=
EBT_ULOG_VERSION
;
do_gettimeofday
(
&
pm
->
stamp
);
if
(
ub
->
qlen
==
1
)
ub
->
skb
->
stamp
=
pm
->
stamp
;
pm
->
data_len
=
copy_len
;
pm
->
mark
=
skb
->
nfmark
;
pm
->
hook
=
hooknr
;
if
(
uloginfo
->
prefix
!=
NULL
)
strcpy
(
pm
->
prefix
,
uloginfo
->
prefix
);
else
*
(
pm
->
prefix
)
=
'\0'
;
if
(
in
)
{
strcpy
(
pm
->
physindev
,
in
->
name
);
/* If in isn't a bridge, then physindev==indev */
if
(
in
->
br_port
)
strcpy
(
pm
->
indev
,
in
->
br_port
->
br
->
dev
->
name
);
else
strcpy
(
pm
->
indev
,
in
->
name
);
}
else
pm
->
indev
[
0
]
=
pm
->
physindev
[
0
]
=
'\0'
;
if
(
out
)
{
/* If out exists, then out is a bridge port */
strcpy
(
pm
->
physoutdev
,
out
->
name
);
strcpy
(
pm
->
outdev
,
out
->
br_port
->
br
->
dev
->
name
);
}
else
pm
->
outdev
[
0
]
=
pm
->
physoutdev
[
0
]
=
'\0'
;
if
(
skb_copy_bits
(
skb
,
-
ETH_HLEN
,
pm
->
data
,
copy_len
)
<
0
)
BUG
();
if
(
ub
->
qlen
>
1
)
ub
->
lastnlh
->
nlmsg_flags
|=
NLM_F_MULTI
;
ub
->
lastnlh
=
nlh
;
if
(
ub
->
qlen
>=
uloginfo
->
qthreshold
)
ulog_send
(
group
);
else
if
(
!
timer_pending
(
&
ub
->
timer
))
{
ub
->
timer
.
expires
=
jiffies
+
flushtimeout
*
HZ
/
100
;
add_timer
(
&
ub
->
timer
);
}
unlock:
spin_unlock_bh
(
lock
);
return
;
nlmsg_failure:
printk
(
KERN_CRIT
"ebt_ulog: error during NLMSG_PUT. This should "
"not happen, please report to author.
\n
"
);
goto
unlock
;
alloc_failure:
goto
unlock
;
}
static
int
ebt_ulog_check
(
const
char
*
tablename
,
unsigned
int
hookmask
,
const
struct
ebt_entry
*
e
,
void
*
data
,
unsigned
int
datalen
)
{
struct
ebt_ulog_info
*
uloginfo
=
(
struct
ebt_ulog_info
*
)
data
;
if
(
datalen
!=
EBT_ALIGN
(
sizeof
(
struct
ebt_ulog_info
))
||
uloginfo
->
nlgroup
>
31
)
return
-
EINVAL
;
uloginfo
->
prefix
[
EBT_ULOG_PREFIX_LEN
-
1
]
=
'\0'
;
if
(
uloginfo
->
qthreshold
>
EBT_ULOG_MAX_QLEN
)
uloginfo
->
qthreshold
=
EBT_ULOG_MAX_QLEN
;
return
0
;
}
static
struct
ebt_watcher
ulog
=
{
.
name
=
EBT_ULOG_WATCHER
,
.
watcher
=
ebt_ulog
,
.
check
=
ebt_ulog_check
,
.
me
=
THIS_MODULE
,
};
static
int
__init
init
(
void
)
{
int
i
,
ret
=
0
;
if
(
nlbufsiz
>=
128
*
1024
)
{
printk
(
KERN_NOTICE
"ebt_ulog: Netlink buffer has to be <= 128kB,"
" please try a smaller nlbufsiz parameter.
\n
"
);
return
-
EINVAL
;
}
/* initialize ulog_buffers */
for
(
i
=
0
;
i
<
EBT_ULOG_MAXNLGROUPS
;
i
++
)
{
init_timer
(
&
ulog_buffers
[
i
].
timer
);
ulog_buffers
[
i
].
timer
.
function
=
ulog_timer
;
ulog_buffers
[
i
].
timer
.
data
=
i
;
ulog_buffers
[
i
].
lock
=
SPIN_LOCK_UNLOCKED
;
}
ebtulognl
=
netlink_kernel_create
(
NETLINK_NFLOG
,
NULL
);
if
(
!
ebtulognl
)
ret
=
-
ENOMEM
;
else
if
((
ret
=
ebt_register_watcher
(
&
ulog
)))
sock_release
(
ebtulognl
->
sk_socket
);
return
ret
;
}
static
void
__exit
fini
(
void
)
{
ebt_ulog_buff_t
*
ub
;
int
i
;
ebt_unregister_watcher
(
&
ulog
);
for
(
i
=
0
;
i
<
EBT_ULOG_MAXNLGROUPS
;
i
++
)
{
ub
=
&
ulog_buffers
[
i
];
if
(
timer_pending
(
&
ub
->
timer
))
del_timer
(
&
ub
->
timer
);
spin_lock_bh
(
&
ub
->
lock
);
if
(
ub
->
skb
)
{
kfree_skb
(
ub
->
skb
);
ub
->
skb
=
NULL
;
}
spin_unlock_bh
(
&
ub
->
lock
);
}
sock_release
(
ebtulognl
->
sk_socket
);
}
module_init
(
init
);
module_exit
(
fini
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Bart De Schuymer <bdschuym@pandora.be>"
);
MODULE_DESCRIPTION
(
"ebtables userspace logging module for bridged Ethernet"
" frames"
);
net/bridge/netfilter/ebtables.c
View file @
fdce75b3
...
@@ -90,10 +90,10 @@ static struct ebt_target ebt_standard_target =
...
@@ -90,10 +90,10 @@ static struct ebt_target ebt_standard_target =
{
{
NULL
,
NULL
},
EBT_STANDARD_TARGET
,
NULL
,
NULL
,
NULL
,
NULL
};
{
{
NULL
,
NULL
},
EBT_STANDARD_TARGET
,
NULL
,
NULL
,
NULL
,
NULL
};
static
inline
int
ebt_do_watcher
(
struct
ebt_entry_watcher
*
w
,
static
inline
int
ebt_do_watcher
(
struct
ebt_entry_watcher
*
w
,
const
struct
sk_buff
*
skb
,
const
struct
net_device
*
in
,
const
struct
sk_buff
*
skb
,
unsigned
int
hooknr
,
const
struct
net_device
*
in
,
const
struct
net_device
*
out
)
const
struct
net_device
*
out
)
{
{
w
->
u
.
watcher
->
watcher
(
skb
,
in
,
out
,
w
->
data
,
w
->
u
.
watcher
->
watcher
(
skb
,
hooknr
,
in
,
out
,
w
->
data
,
w
->
watcher_size
);
w
->
watcher_size
);
/* watchers don't give a verdict */
/* watchers don't give a verdict */
return
0
;
return
0
;
...
@@ -208,7 +208,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
...
@@ -208,7 +208,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb,
/* these should only watch: not modify, nor tell us
/* these should only watch: not modify, nor tell us
what to do with the packet */
what to do with the packet */
EBT_WATCHER_ITERATE
(
point
,
ebt_do_watcher
,
*
pskb
,
in
,
EBT_WATCHER_ITERATE
(
point
,
ebt_do_watcher
,
*
pskb
,
hook
,
in
,
out
);
out
);
t
=
(
struct
ebt_entry_target
*
)
t
=
(
struct
ebt_entry_target
*
)
...
...
net/core/dev.c
View file @
fdce75b3
...
@@ -1493,7 +1493,7 @@ int netif_rx_ni(struct sk_buff *skb)
...
@@ -1493,7 +1493,7 @@ int netif_rx_ni(struct sk_buff *skb)
preempt_disable
();
preempt_disable
();
err
=
netif_rx
(
skb
);
err
=
netif_rx
(
skb
);
if
(
softirq_pending
(
smp_processor_id
()
))
if
(
local_softirq_pending
(
))
do_softirq
();
do_softirq
();
preempt_enable
();
preempt_enable
();
...
@@ -2700,8 +2700,7 @@ static inline void net_set_todo(struct net_device *dev)
...
@@ -2700,8 +2700,7 @@ static inline void net_set_todo(struct net_device *dev)
* chain. 0 is returned on success. A negative errno code is returned
* chain. 0 is returned on success. A negative errno code is returned
* on a failure to set up the device, or if the name is a duplicate.
* on a failure to set up the device, or if the name is a duplicate.
*
*
* Callers must hold the rtnl semaphore. See the comment at the
* Callers must hold the rtnl semaphore. You may want
* end of Space.c for details about the locking. You may want
* register_netdev() instead of this.
* register_netdev() instead of this.
*
*
* BUGS:
* BUGS:
...
@@ -2822,6 +2821,51 @@ int register_netdevice(struct net_device *dev)
...
@@ -2822,6 +2821,51 @@ int register_netdevice(struct net_device *dev)
goto
out
;
goto
out
;
}
}
/**
* register_netdev - register a network device
* @dev: device to register
*
* Take a completed network device structure and add it to the kernel
* interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
* chain. 0 is returned on success. A negative errno code is returned
* on a failure to set up the device, or if the name is a duplicate.
*
* This is a wrapper around register_netdev that takes the rtnl semaphore
* and expands the device name if you passed a format string to
* alloc_netdev.
*/
int
register_netdev
(
struct
net_device
*
dev
)
{
int
err
;
rtnl_lock
();
/*
* If the name is a format string the caller wants us to do a
* name allocation.
*/
if
(
strchr
(
dev
->
name
,
'%'
))
{
err
=
dev_alloc_name
(
dev
,
dev
->
name
);
if
(
err
<
0
)
goto
out
;
}
/*
* Back compatibility hook. Kill this one in 2.5
*/
if
(
dev
->
name
[
0
]
==
0
||
dev
->
name
[
0
]
==
' '
)
{
err
=
dev_alloc_name
(
dev
,
"eth%d"
);
if
(
err
<
0
)
goto
out
;
}
err
=
register_netdevice
(
dev
);
out:
rtnl_unlock
();
return
err
;
}
EXPORT_SYMBOL
(
register_netdev
);
/*
/*
* netdev_wait_allrefs - wait until all references are gone.
* netdev_wait_allrefs - wait until all references are gone.
*
*
...
@@ -2964,6 +3008,46 @@ void netdev_run_todo(void)
...
@@ -2964,6 +3008,46 @@ void netdev_run_todo(void)
up
(
&
net_todo_run_mutex
);
up
(
&
net_todo_run_mutex
);
}
}
/**
* alloc_netdev - allocate network device
* @sizeof_priv: size of private data to allocate space for
* @name: device name format string
* @setup: callback to initialize device
*
* Allocates a struct net_device with private data area for driver use
* and performs basic initialization.
*/
struct
net_device
*
alloc_netdev
(
int
sizeof_priv
,
const
char
*
name
,
void
(
*
setup
)(
struct
net_device
*
))
{
void
*
p
;
struct
net_device
*
dev
;
int
alloc_size
;
/* ensure 32-byte alignment of both the device and private area */
alloc_size
=
(
sizeof
(
*
dev
)
+
NETDEV_ALIGN_CONST
)
&
~
NETDEV_ALIGN_CONST
;
alloc_size
+=
sizeof_priv
+
NETDEV_ALIGN_CONST
;
p
=
kmalloc
(
alloc_size
,
GFP_KERNEL
);
if
(
!
p
)
{
printk
(
KERN_ERR
"alloc_dev: Unable to allocate device.
\n
"
);
return
NULL
;
}
memset
(
p
,
0
,
alloc_size
);
dev
=
(
struct
net_device
*
)
(((
long
)
p
+
NETDEV_ALIGN_CONST
)
&
~
NETDEV_ALIGN_CONST
);
dev
->
padded
=
(
char
*
)
dev
-
(
char
*
)
p
;
if
(
sizeof_priv
)
dev
->
priv
=
netdev_priv
(
dev
);
setup
(
dev
);
strcpy
(
dev
->
name
,
name
);
return
dev
;
}
EXPORT_SYMBOL
(
alloc_netdev
);
/**
/**
* free_netdev - free network device
* free_netdev - free network device
* @dev: device
* @dev: device
...
@@ -3006,8 +3090,7 @@ void synchronize_net(void)
...
@@ -3006,8 +3090,7 @@ void synchronize_net(void)
* from the kernel tables. On success 0 is returned, on a failure
* from the kernel tables. On success 0 is returned, on a failure
* a negative errno code is returned.
* a negative errno code is returned.
*
*
* Callers must hold the rtnl semaphore. See the comment at the
* Callers must hold the rtnl semaphore. You may want
* end of Space.c for details about the locking. You may want
* unregister_netdev() instead of this.
* unregister_netdev() instead of this.
*/
*/
...
@@ -3085,6 +3168,27 @@ int unregister_netdevice(struct net_device *dev)
...
@@ -3085,6 +3168,27 @@ int unregister_netdevice(struct net_device *dev)
return
0
;
return
0
;
}
}
/**
* unregister_netdev - remove device from the kernel
* @dev: device
*
* This function shuts down a device interface and removes it
* from the kernel tables. On success 0 is returned, on a failure
* a negative errno code is returned.
*
* This is just a wrapper for unregister_netdevice that takes
* the rtnl semaphore. In general you want to use this and not
* unregister_netdevice.
*/
void
unregister_netdev
(
struct
net_device
*
dev
)
{
rtnl_lock
();
unregister_netdevice
(
dev
);
rtnl_unlock
();
}
EXPORT_SYMBOL
(
unregister_netdev
);
#ifdef CONFIG_HOTPLUG_CPU
#ifdef CONFIG_HOTPLUG_CPU
static
int
dev_cpu_callback
(
struct
notifier_block
*
nfb
,
static
int
dev_cpu_callback
(
struct
notifier_block
*
nfb
,
unsigned
long
action
,
unsigned
long
action
,
...
...
net/core/skbuff.c
View file @
fdce75b3
...
@@ -163,6 +163,59 @@ struct sk_buff *alloc_skb(unsigned int size, int gfp_mask)
...
@@ -163,6 +163,59 @@ struct sk_buff *alloc_skb(unsigned int size, int gfp_mask)
goto
out
;
goto
out
;
}
}
/**
* alloc_skb_from_cache - allocate a network buffer
* @cp: kmem_cache from which to allocate the data area
* (object size must be big enough for @size bytes + skb overheads)
* @size: size to allocate
* @gfp_mask: allocation mask
*
* Allocate a new &sk_buff. The returned buffer has no headroom and
* tail room of size bytes. The object has a reference count of one.
* The return is the buffer. On a failure the return is %NULL.
*
* Buffers may only be allocated from interrupts using a @gfp_mask of
* %GFP_ATOMIC.
*/
struct
sk_buff
*
alloc_skb_from_cache
(
kmem_cache_t
*
cp
,
unsigned
int
size
,
int
gfp_mask
)
{
struct
sk_buff
*
skb
;
u8
*
data
;
/* Get the HEAD */
skb
=
kmem_cache_alloc
(
skbuff_head_cache
,
gfp_mask
&
~
__GFP_DMA
);
if
(
!
skb
)
goto
out
;
/* Get the DATA. */
size
=
SKB_DATA_ALIGN
(
size
);
data
=
kmem_cache_alloc
(
cp
,
gfp_mask
);
if
(
!
data
)
goto
nodata
;
memset
(
skb
,
0
,
offsetof
(
struct
sk_buff
,
truesize
));
skb
->
truesize
=
size
+
sizeof
(
struct
sk_buff
);
atomic_set
(
&
skb
->
users
,
1
);
skb
->
head
=
data
;
skb
->
data
=
data
;
skb
->
tail
=
data
;
skb
->
end
=
data
+
size
;
atomic_set
(
&
(
skb_shinfo
(
skb
)
->
dataref
),
1
);
skb_shinfo
(
skb
)
->
nr_frags
=
0
;
skb_shinfo
(
skb
)
->
tso_size
=
0
;
skb_shinfo
(
skb
)
->
tso_segs
=
0
;
skb_shinfo
(
skb
)
->
frag_list
=
NULL
;
out:
return
skb
;
nodata:
kmem_cache_free
(
skbuff_head_cache
,
skb
);
skb
=
NULL
;
goto
out
;
}
static
void
skb_drop_fraglist
(
struct
sk_buff
*
skb
)
static
void
skb_drop_fraglist
(
struct
sk_buff
*
skb
)
{
{
...
...
net/sched/Kconfig
View file @
fdce75b3
...
@@ -334,6 +334,18 @@ config NET_CLS_IND
...
@@ -334,6 +334,18 @@ config NET_CLS_IND
Requires a new iproute2
Requires a new iproute2
You MUST NOT turn this on if you dont have an update iproute2.
You MUST NOT turn this on if you dont have an update iproute2.
config CLS_U32_MARK
bool "Use nfmark as a key in U32 classifier"
depends on NET_CLS_U32 && NETFILTER
help
This allows you to match mark in a u32 filter.
Example:
tc filter add dev eth0 protocol ip parent 1:0 prio 5 u32 \
match mark 0x0090 0xffff \
match ip dst 4.4.4.4 \
flowid 1:90
You must use a new iproute2 to use this feature.
config NET_CLS_RSVP
config NET_CLS_RSVP
tristate "Special RSVP classifier"
tristate "Special RSVP classifier"
depends on NET_CLS && NET_QOS
depends on NET_CLS && NET_QOS
...
...
net/sched/act_api.c
View file @
fdce75b3
...
@@ -294,14 +294,16 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int re
...
@@ -294,14 +294,16 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *act, int bind, int re
}
}
int
tcf_action_init_1
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
struct
tc_action
*
a
,
char
*
name
,
int
ovr
,
int
bind
)
struct
tc_action
*
tcf_action_init_1
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
char
*
name
,
int
ovr
,
int
bind
,
int
*
err
)
{
{
struct
tc_action
*
a
;
struct
tc_action_ops
*
a_o
;
struct
tc_action_ops
*
a_o
;
char
act_name
[
4
+
IFNAMSIZ
+
1
];
char
act_name
[
4
+
IFNAMSIZ
+
1
];
struct
rtattr
*
tb
[
TCA_ACT_MAX
+
1
];
struct
rtattr
*
tb
[
TCA_ACT_MAX
+
1
];
struct
rtattr
*
kind
=
NULL
;
struct
rtattr
*
kind
=
NULL
;
int
err
=
-
EINVAL
;
*
err
=
-
EINVAL
;
if
(
NULL
==
name
)
{
if
(
NULL
==
name
)
{
if
(
rtattr_parse
(
tb
,
TCA_ACT_MAX
,
RTA_DATA
(
rta
),
RTA_PAYLOAD
(
rta
))
<
0
)
if
(
rtattr_parse
(
tb
,
TCA_ACT_MAX
,
RTA_DATA
(
rta
),
RTA_PAYLOAD
(
rta
))
<
0
)
...
@@ -337,22 +339,25 @@ int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *
...
@@ -337,22 +339,25 @@ int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *
goto
err_out
;
goto
err_out
;
}
}
if
(
NULL
==
a
)
{
a
=
kmalloc
(
sizeof
(
*
a
),
GFP_KERNEL
);
if
(
a
==
NULL
)
{
*
err
=
-
ENOMEM
;
goto
err_mod
;
goto
err_mod
;
}
}
memset
(
a
,
0
,
sizeof
(
*
a
));
/* backward compatibility for policer */
/* backward compatibility for policer */
if
(
NULL
==
name
)
{
if
(
NULL
==
name
)
{
err
=
a_o
->
init
(
tb
[
TCA_ACT_OPTIONS
-
1
],
est
,
a
,
ovr
,
bind
);
*
err
=
a_o
->
init
(
tb
[
TCA_ACT_OPTIONS
-
1
],
est
,
a
,
ovr
,
bind
);
if
(
0
>
err
)
{
if
(
*
err
<
0
)
{
err
=
-
EINVAL
;
*
err
=
-
EINVAL
;
goto
err_
mod
;
goto
err_
free
;
}
}
}
else
{
}
else
{
err
=
a_o
->
init
(
rta
,
est
,
a
,
ovr
,
bind
);
*
err
=
a_o
->
init
(
rta
,
est
,
a
,
ovr
,
bind
);
if
(
0
>
err
)
{
if
(
*
err
<
0
)
{
err
=
-
EINVAL
;
*
err
=
-
EINVAL
;
goto
err_
mod
;
goto
err_
free
;
}
}
}
}
...
@@ -360,60 +365,58 @@ int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *
...
@@ -360,60 +365,58 @@ int tcf_action_init_1(struct rtattr *rta, struct rtattr *est, struct tc_action *
if it exists and is only bound to in a_o->init() then
if it exists and is only bound to in a_o->init() then
ACT_P_CREATED is not returned (a zero is).
ACT_P_CREATED is not returned (a zero is).
*/
*/
if
(
ACT_P_CREATED
!=
err
)
{
if
(
*
err
!=
ACT_P_CREATED
)
module_put
(
a_o
->
owner
);
module_put
(
a_o
->
owner
);
}
a
->
ops
=
a_o
;
a
->
ops
=
a_o
;
DPRINTK
(
"tcf_action_init_1: successfull %s
\n
"
,
act_name
);
DPRINTK
(
"tcf_action_init_1: successfull %s
\n
"
,
act_name
);
return
0
;
*
err
=
0
;
return
a
;
err_free:
kfree
(
a
);
err_mod:
err_mod:
module_put
(
a_o
->
owner
);
module_put
(
a_o
->
owner
);
err_out:
err_out:
return
err
;
return
NULL
;
}
}
int
tcf_action_init
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
struct
tc_action
*
a
,
char
*
name
,
int
ovr
,
int
bind
)
struct
tc_action
*
tcf_action_init
(
struct
rtattr
*
rta
,
struct
rtattr
*
est
,
char
*
name
,
int
ovr
,
int
bind
,
int
*
err
)
{
{
struct
rtattr
*
tb
[
TCA_ACT_MAX_PRIO
+
1
];
struct
rtattr
*
tb
[
TCA_ACT_MAX_PRIO
+
1
];
struct
tc_action
*
a
=
NULL
,
*
act
,
*
act_prev
=
NULL
;
int
i
;
int
i
;
struct
tc_action
*
act
=
a
,
*
a_s
=
a
;
int
err
=
-
EINVAL
;
if
(
rtattr_parse
(
tb
,
TCA_ACT_MAX_PRIO
,
RTA_DATA
(
rta
),
RTA_PAYLOAD
(
rta
))
<
0
)
if
(
rtattr_parse
(
tb
,
TCA_ACT_MAX_PRIO
,
RTA_DATA
(
rta
),
return
err
;
RTA_PAYLOAD
(
rta
))
<
0
)
{
*
err
=
-
EINVAL
;
return
a
;
}
for
(
i
=
0
;
i
<
TCA_ACT_MAX_PRIO
;
i
++
)
{
for
(
i
=
0
;
i
<
TCA_ACT_MAX_PRIO
;
i
++
)
{
if
(
tb
[
i
])
{
if
(
tb
[
i
])
{
if
(
NULL
==
act
)
{
act
=
tcf_action_init_1
(
tb
[
i
],
est
,
name
,
ovr
,
bind
,
err
);
act
=
kmalloc
(
sizeof
(
*
act
),
GFP_KERNEL
);
if
(
act
==
NULL
)
{
if
(
NULL
==
act
)
{
printk
(
"Error processing action order %d
\n
"
,
i
);
err
=
-
ENOMEM
;
goto
bad_ret
;
goto
bad_ret
;
}
memset
(
act
,
0
,
sizeof
(
*
act
));
}
act
->
next
=
NULL
;
if
(
0
>
tcf_action_init_1
(
tb
[
i
],
est
,
act
,
name
,
ovr
,
bind
))
{
printk
(
"Error processing action order %d
\n
"
,
i
);
return
err
;
}
}
act
->
order
=
i
+
1
;
act
->
order
=
i
+
1
;
if
(
a
_s
!=
act
)
{
if
(
a
==
NULL
)
a
_s
->
next
=
act
;
a
=
act
;
a_s
=
act
;
else
}
act_prev
->
next
=
act
;
act
=
NULL
;
act
_prev
=
act
;
}
}
}
}
return
a
;
return
0
;
bad_ret:
bad_ret:
tcf_action_destroy
(
a
,
bind
);
if
(
a
!=
NULL
)
return
err
;
tcf_action_destroy
(
a
,
bind
);
return
NULL
;
}
}
int
tcf_action_copy_stats
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
)
int
tcf_action_copy_stats
(
struct
sk_buff
*
skb
,
struct
tc_action
*
a
)
...
@@ -849,21 +852,9 @@ static int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int o
...
@@ -849,21 +852,9 @@ static int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int o
struct
tc_action
*
a
=
NULL
;
struct
tc_action
*
a
=
NULL
;
u32
seq
=
n
->
nlmsg_seq
;
u32
seq
=
n
->
nlmsg_seq
;
act
=
kmalloc
(
sizeof
(
*
act
),
GFP_KERNEL
);
act
=
tcf_action_init
(
rta
,
NULL
,
NULL
,
ovr
,
0
,
&
ret
);
if
(
NULL
==
act
)
if
(
act
==
NULL
)
return
-
ENOMEM
;
memset
(
act
,
0
,
sizeof
(
*
act
));
ret
=
tcf_action_init
(
rta
,
NULL
,
act
,
NULL
,
ovr
,
0
);
/* NOTE: We have an all-or-none model
* This means that of any of the actions fail
* to update then all are undone.
* */
if
(
0
>
ret
)
{
tcf_action_destroy
(
act
,
0
);
goto
done
;
goto
done
;
}
/* dump then free all the actions after update; inserted policy
/* dump then free all the actions after update; inserted policy
* stays intact
* stays intact
...
@@ -880,7 +871,6 @@ static int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int o
...
@@ -880,7 +871,6 @@ static int tcf_action_add(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int o
}
}
}
}
done:
done:
return
ret
;
return
ret
;
}
}
...
...
net/sched/cls_u32.c
View file @
fdce75b3
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
* JHS: We should remove the CONFIG_NET_CLS_IND from here
* JHS: We should remove the CONFIG_NET_CLS_IND from here
* eventually when the meta match extension is made available
* eventually when the meta match extension is made available
*
*
* nfmark match added by Catalin(ux aka Dino) BOIE <catab at umbrella.ro>
*/
*/
#include <asm/uaccess.h>
#include <asm/uaccess.h>
...
@@ -58,6 +59,13 @@
...
@@ -58,6 +59,13 @@
#include <net/pkt_cls.h>
#include <net/pkt_cls.h>
struct
tc_u32_mark
{
__u32
val
;
__u32
mask
;
__u32
success
;
};
struct
tc_u_knode
struct
tc_u_knode
{
{
struct
tc_u_knode
*
next
;
struct
tc_u_knode
*
next
;
...
@@ -78,6 +86,9 @@ struct tc_u_knode
...
@@ -78,6 +86,9 @@ struct tc_u_knode
struct
tc_u_hnode
*
ht_down
;
struct
tc_u_hnode
*
ht_down
;
#ifdef CONFIG_CLS_U32_PERF
#ifdef CONFIG_CLS_U32_PERF
struct
tc_u32_pcnt
*
pf
;
struct
tc_u32_pcnt
*
pf
;
#endif
#ifdef CONFIG_CLS_U32_MARK
struct
tc_u32_mark
mark
;
#endif
#endif
struct
tc_u32_sel
sel
;
struct
tc_u32_sel
sel
;
};
};
...
@@ -139,6 +150,16 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
...
@@ -139,6 +150,16 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
n
->
pf
->
rcnt
+=
1
;
n
->
pf
->
rcnt
+=
1
;
j
=
0
;
j
=
0
;
#endif
#endif
#ifdef CONFIG_CLS_U32_MARK
if
((
skb
->
nfmark
&
n
->
mark
.
mask
)
!=
n
->
mark
.
val
)
{
n
=
n
->
next
;
goto
next_knode
;
}
else
{
n
->
mark
.
success
++
;
}
#endif
for
(
i
=
n
->
sel
.
nkeys
;
i
>
0
;
i
--
,
key
++
)
{
for
(
i
=
n
->
sel
.
nkeys
;
i
>
0
;
i
--
,
key
++
)
{
if
((
*
(
u32
*
)(
ptr
+
key
->
off
+
(
off2
&
key
->
offmask
))
^
key
->
val
)
&
key
->
mask
)
{
if
((
*
(
u32
*
)(
ptr
+
key
->
off
+
(
off2
&
key
->
offmask
))
^
key
->
val
)
&
key
->
mask
)
{
...
@@ -554,6 +575,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
...
@@ -554,6 +575,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
struct
tc_u_hnode
*
ht
;
struct
tc_u_hnode
*
ht
;
struct
tc_u_knode
*
n
;
struct
tc_u_knode
*
n
;
struct
tc_u32_sel
*
s
;
struct
tc_u32_sel
*
s
;
struct
tc_u32_mark
*
mark
;
struct
rtattr
*
opt
=
tca
[
TCA_OPTIONS
-
1
];
struct
rtattr
*
opt
=
tca
[
TCA_OPTIONS
-
1
];
struct
rtattr
*
tb
[
TCA_U32_MAX
];
struct
rtattr
*
tb
[
TCA_U32_MAX
];
u32
htid
;
u32
htid
;
...
@@ -657,6 +679,17 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
...
@@ -657,6 +679,17 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
}
}
n
->
fshift
=
i
;
n
->
fshift
=
i
;
}
}
#ifdef CONFIG_CLS_U32_MARK
if
(
tb
[
TCA_U32_MARK
-
1
])
{
if
(
RTA_PAYLOAD
(
tb
[
TCA_U32_MARK
-
1
])
<
sizeof
(
struct
tc_u32_mark
))
return
-
EINVAL
;
mark
=
RTA_DATA
(
tb
[
TCA_U32_MARK
-
1
]);
memcpy
(
&
n
->
mark
,
mark
,
sizeof
(
struct
tc_u32_mark
));
n
->
mark
.
success
=
0
;
}
#endif
err
=
u32_set_parms
(
tp
,
base
,
ht
,
n
,
tb
,
tca
[
TCA_RATE
-
1
]);
err
=
u32_set_parms
(
tp
,
base
,
ht
,
n
,
tb
,
tca
[
TCA_RATE
-
1
]);
if
(
err
==
0
)
{
if
(
err
==
0
)
{
struct
tc_u_knode
**
ins
;
struct
tc_u_knode
**
ins
;
...
@@ -744,6 +777,12 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
...
@@ -744,6 +777,12 @@ static int u32_dump(struct tcf_proto *tp, unsigned long fh,
RTA_PUT
(
skb
,
TCA_U32_CLASSID
,
4
,
&
n
->
res
.
classid
);
RTA_PUT
(
skb
,
TCA_U32_CLASSID
,
4
,
&
n
->
res
.
classid
);
if
(
n
->
ht_down
)
if
(
n
->
ht_down
)
RTA_PUT
(
skb
,
TCA_U32_LINK
,
4
,
&
n
->
ht_down
->
handle
);
RTA_PUT
(
skb
,
TCA_U32_LINK
,
4
,
&
n
->
ht_down
->
handle
);
#ifdef CONFIG_CLS_U32_MARK
if
(
n
->
mark
.
val
||
n
->
mark
.
mask
)
RTA_PUT
(
skb
,
TCA_U32_MARK
,
sizeof
(
n
->
mark
),
&
n
->
mark
);
#endif
#ifdef CONFIG_NET_CLS_ACT
#ifdef CONFIG_NET_CLS_ACT
if
(
tcf_dump_act
(
skb
,
n
->
action
,
TCA_U32_ACT
,
TCA_U32_POLICE
)
<
0
)
if
(
tcf_dump_act
(
skb
,
n
->
action
,
TCA_U32_ACT
,
TCA_U32_POLICE
)
<
0
)
goto
rtattr_failure
;
goto
rtattr_failure
;
...
...
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