[LLC]: Do better struct sock accounting on skbs
Signed-off-by: Jochen Friedrich <jochen@scram.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
index 6dd4cdc..9dcfcf4 100644
--- a/include/net/llc_sap.h
+++ b/include/net/llc_sap.h
@@ -12,11 +12,13 @@
* See the GNU General Public License for more details.
*/
struct llc_sap;
-struct sk_buff;
struct net_device;
+struct sk_buff;
+struct sock;
extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
-extern void llc_save_primitive(struct sk_buff* skb, unsigned char prim);
+extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb,
+ unsigned char prim);
extern struct sk_buff *llc_alloc_frame(struct net_device *dev);
extern void llc_build_and_send_test_pkt(struct llc_sap *sap,
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index f536369..ad9aad8 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -628,7 +628,6 @@
/* put original socket back into a clean listen state. */
sk->sk_state = TCP_LISTEN;
sk->sk_ack_backlog--;
- skb->sk = NULL;
dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__,
llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap);
frees:
@@ -740,7 +739,6 @@
lock_sock(sk);
if (!skb)
goto release;
- skb->sk = sk;
skb->dev = llc->dev;
skb->protocol = llc_proto_type(addr->sllc_arphrd);
skb_reserve(skb, hdrlen);
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 9d9b6c8a..c1e7510 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -1335,7 +1335,7 @@
if (skb) {
struct llc_conn_state_ev *ev = llc_conn_ev(skb);
- skb->sk = sk;
+ skb_set_owner_r(skb, sk);
ev->type = type;
llc_process_tmr_ev(sk, skb);
}
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index d3783f8..9f0e10e 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -90,8 +90,8 @@
switch (ev->ind_prim) {
case LLC_DATA_PRIM:
- llc_save_primitive(skb, LLC_DATA_PRIM);
- if (sock_queue_rcv_skb(sk, skb)) {
+ llc_save_primitive(sk, skb, LLC_DATA_PRIM);
+ if (unlikely(sock_queue_rcv_skb(sk, skb))) {
/*
* shouldn't happen
*/
@@ -103,6 +103,11 @@
case LLC_CONN_PRIM: {
struct sock *parent = skb->sk;
+ skb_orphan(skb);
+ /*
+ * Set the skb->sk to the new struct sock, so that at accept
+ * type the upper layer can get the newly created struct sock.
+ */
skb->sk = sk;
skb_queue_tail(&parent->sk_receive_queue, skb);
sk->sk_state_change(parent);
@@ -702,10 +707,9 @@
memcpy(&llc->daddr, &saddr, sizeof(llc->daddr));
llc_sap_add_socket(sap, sk);
sock_hold(sk);
+ skb_set_owner_r(skb, parent);
sock_put(parent);
- skb->sk = parent;
- } else
- skb->sk = sk;
+ }
bh_lock_sock(sk);
if (!sock_owned_by_user(sk))
llc_conn_rcv(sk, skb);
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c
index 0adaa28..9f064b3 100644
--- a/net/llc/llc_sap.c
+++ b/net/llc/llc_sap.c
@@ -45,12 +45,12 @@
return skb;
}
-void llc_save_primitive(struct sk_buff* skb, u8 prim)
+void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim)
{
struct sockaddr_llc *addr = llc_ui_skb_cb(skb);
/* save primitive for use by the user. */
- addr->sllc_family = skb->sk->sk_family;
+ addr->sllc_family = sk->sk_family;
addr->sllc_arphrd = skb->dev->type;
addr->sllc_test = prim == LLC_TEST_PRIM;
addr->sllc_xid = prim == LLC_XID_PRIM;
@@ -190,7 +190,7 @@
if (skb->sk->sk_state == TCP_LISTEN)
kfree_skb(skb);
else {
- llc_save_primitive(skb, ev->prim);
+ llc_save_primitive(skb->sk, skb, ev->prim);
/* queue skb to the user. */
if (sock_queue_rcv_skb(skb->sk, skb))
@@ -309,7 +309,7 @@
sk = llc_lookup_dgram(sap, &laddr);
if (sk) {
- skb->sk = sk;
+ skb_set_owner_r(skb, sk);
llc_sap_rcv(sap, skb);
sock_put(sk);
} else