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
Kirill Smelkov
linux
Commits
ce06b03e
Commit
ce06b03e
authored
Jul 04, 2011
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
packet: Add helpers to register/unregister ->prot_hook
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
f8bae99e
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
59 additions
and
44 deletions
+59
-44
net/packet/af_packet.c
net/packet/af_packet.c
+59
-44
No files found.
net/packet/af_packet.c
View file @
ce06b03e
...
...
@@ -222,6 +222,55 @@ struct packet_skb_cb {
#define PACKET_SKB_CB(__skb) ((struct packet_skb_cb *)((__skb)->cb))
static
inline
struct
packet_sock
*
pkt_sk
(
struct
sock
*
sk
)
{
return
(
struct
packet_sock
*
)
sk
;
}
/* register_prot_hook must be invoked with the po->bind_lock held,
* or from a context in which asynchronous accesses to the packet
* socket is not possible (packet_create()).
*/
static
void
register_prot_hook
(
struct
sock
*
sk
)
{
struct
packet_sock
*
po
=
pkt_sk
(
sk
);
if
(
!
po
->
running
)
{
dev_add_pack
(
&
po
->
prot_hook
);
sock_hold
(
sk
);
po
->
running
=
1
;
}
}
/* {,__}unregister_prot_hook() must be invoked with the po->bind_lock
* held. If the sync parameter is true, we will temporarily drop
* the po->bind_lock and do a synchronize_net to make sure no
* asynchronous packet processing paths still refer to the elements
* of po->prot_hook. If the sync parameter is false, it is the
* callers responsibility to take care of this.
*/
static
void
__unregister_prot_hook
(
struct
sock
*
sk
,
bool
sync
)
{
struct
packet_sock
*
po
=
pkt_sk
(
sk
);
po
->
running
=
0
;
__dev_remove_pack
(
&
po
->
prot_hook
);
__sock_put
(
sk
);
if
(
sync
)
{
spin_unlock
(
&
po
->
bind_lock
);
synchronize_net
();
spin_lock
(
&
po
->
bind_lock
);
}
}
static
void
unregister_prot_hook
(
struct
sock
*
sk
,
bool
sync
)
{
struct
packet_sock
*
po
=
pkt_sk
(
sk
);
if
(
po
->
running
)
__unregister_prot_hook
(
sk
,
sync
);
}
static
inline
__pure
struct
page
*
pgv_to_page
(
void
*
addr
)
{
if
(
is_vmalloc_addr
(
addr
))
...
...
@@ -324,11 +373,6 @@ static inline void packet_increment_head(struct packet_ring_buffer *buff)
buff
->
head
=
buff
->
head
!=
buff
->
frame_max
?
buff
->
head
+
1
:
0
;
}
static
inline
struct
packet_sock
*
pkt_sk
(
struct
sock
*
sk
)
{
return
(
struct
packet_sock
*
)
sk
;
}
static
void
packet_sock_destruct
(
struct
sock
*
sk
)
{
skb_queue_purge
(
&
sk
->
sk_error_queue
);
...
...
@@ -1337,15 +1381,7 @@ static int packet_release(struct socket *sock)
spin_unlock_bh
(
&
net
->
packet
.
sklist_lock
);
spin_lock
(
&
po
->
bind_lock
);
if
(
po
->
running
)
{
/*
* Remove from protocol table
*/
po
->
running
=
0
;
po
->
num
=
0
;
__dev_remove_pack
(
&
po
->
prot_hook
);
__sock_put
(
sk
);
}
unregister_prot_hook
(
sk
,
false
);
if
(
po
->
prot_hook
.
dev
)
{
dev_put
(
po
->
prot_hook
.
dev
);
po
->
prot_hook
.
dev
=
NULL
;
...
...
@@ -1392,15 +1428,7 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
lock_sock
(
sk
);
spin_lock
(
&
po
->
bind_lock
);
if
(
po
->
running
)
{
__sock_put
(
sk
);
po
->
running
=
0
;
po
->
num
=
0
;
spin_unlock
(
&
po
->
bind_lock
);
dev_remove_pack
(
&
po
->
prot_hook
);
spin_lock
(
&
po
->
bind_lock
);
}
unregister_prot_hook
(
sk
,
true
);
po
->
num
=
protocol
;
po
->
prot_hook
.
type
=
protocol
;
if
(
po
->
prot_hook
.
dev
)
...
...
@@ -1413,9 +1441,7 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc
goto
out_unlock
;
if
(
!
dev
||
(
dev
->
flags
&
IFF_UP
))
{
dev_add_pack
(
&
po
->
prot_hook
);
sock_hold
(
sk
);
po
->
running
=
1
;
register_prot_hook
(
sk
);
}
else
{
sk
->
sk_err
=
ENETDOWN
;
if
(
!
sock_flag
(
sk
,
SOCK_DEAD
))
...
...
@@ -1542,9 +1568,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
if
(
proto
)
{
po
->
prot_hook
.
type
=
proto
;
dev_add_pack
(
&
po
->
prot_hook
);
sock_hold
(
sk
);
po
->
running
=
1
;
register_prot_hook
(
sk
);
}
spin_lock_bh
(
&
net
->
packet
.
sklist_lock
);
...
...
@@ -2240,9 +2264,7 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
if
(
dev
->
ifindex
==
po
->
ifindex
)
{
spin_lock
(
&
po
->
bind_lock
);
if
(
po
->
running
)
{
__dev_remove_pack
(
&
po
->
prot_hook
);
__sock_put
(
sk
);
po
->
running
=
0
;
__unregister_prot_hook
(
sk
,
false
);
sk
->
sk_err
=
ENETDOWN
;
if
(
!
sock_flag
(
sk
,
SOCK_DEAD
))
sk
->
sk_error_report
(
sk
);
...
...
@@ -2259,11 +2281,8 @@ static int packet_notifier(struct notifier_block *this, unsigned long msg, void
case
NETDEV_UP
:
if
(
dev
->
ifindex
==
po
->
ifindex
)
{
spin_lock
(
&
po
->
bind_lock
);
if
(
po
->
num
&&
!
po
->
running
)
{
dev_add_pack
(
&
po
->
prot_hook
);
sock_hold
(
sk
);
po
->
running
=
1
;
}
if
(
po
->
num
)
register_prot_hook
(
sk
);
spin_unlock
(
&
po
->
bind_lock
);
}
break
;
...
...
@@ -2530,10 +2549,8 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
was_running
=
po
->
running
;
num
=
po
->
num
;
if
(
was_running
)
{
__dev_remove_pack
(
&
po
->
prot_hook
);
po
->
num
=
0
;
po
->
running
=
0
;
__sock_put
(
sk
);
__unregister_prot_hook
(
sk
,
false
);
}
spin_unlock
(
&
po
->
bind_lock
);
...
...
@@ -2564,11 +2581,9 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
mutex_unlock
(
&
po
->
pg_vec_lock
);
spin_lock
(
&
po
->
bind_lock
);
if
(
was_running
&&
!
po
->
running
)
{
sock_hold
(
sk
);
po
->
running
=
1
;
if
(
was_running
)
{
po
->
num
=
num
;
dev_add_pack
(
&
po
->
prot_hoo
k
);
register_prot_hook
(
s
k
);
}
spin_unlock
(
&
po
->
bind_lock
);
...
...
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