diff options
Diffstat (limited to 'net/llc/llc_sap.c')
| -rw-r--r-- | net/llc/llc_sap.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 34228ef14985..4029ceee9b91 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c | |||
| @@ -26,11 +26,12 @@ | |||
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | * llc_alloc_frame - allocates sk_buff for frame | 28 | * llc_alloc_frame - allocates sk_buff for frame |
| 29 | * @dev: network device this skb will be sent over | ||
| 29 | * | 30 | * |
| 30 | * Allocates an sk_buff for frame and initializes sk_buff fields. | 31 | * Allocates an sk_buff for frame and initializes sk_buff fields. |
| 31 | * Returns allocated skb or %NULL when out of memory. | 32 | * Returns allocated skb or %NULL when out of memory. |
| 32 | */ | 33 | */ |
| 33 | struct sk_buff *llc_alloc_frame(void) | 34 | struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev) |
| 34 | { | 35 | { |
| 35 | struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); | 36 | struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); |
| 36 | 37 | ||
| @@ -38,18 +39,23 @@ struct sk_buff *llc_alloc_frame(void) | |||
| 38 | skb_reserve(skb, 50); | 39 | skb_reserve(skb, 50); |
| 39 | skb->nh.raw = skb->h.raw = skb->data; | 40 | skb->nh.raw = skb->h.raw = skb->data; |
| 40 | skb->protocol = htons(ETH_P_802_2); | 41 | skb->protocol = htons(ETH_P_802_2); |
| 41 | skb->dev = dev_base->next; | 42 | skb->dev = dev; |
| 42 | skb->mac.raw = skb->head; | 43 | skb->mac.raw = skb->head; |
| 44 | if (sk != NULL) | ||
| 45 | skb_set_owner_w(skb, sk); | ||
| 43 | } | 46 | } |
| 44 | return skb; | 47 | return skb; |
| 45 | } | 48 | } |
| 46 | 49 | ||
| 47 | void llc_save_primitive(struct sk_buff* skb, u8 prim) | 50 | void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim) |
| 48 | { | 51 | { |
| 49 | struct sockaddr_llc *addr = llc_ui_skb_cb(skb); | 52 | struct sockaddr_llc *addr; |
| 50 | 53 | ||
| 54 | if (skb->sk->sk_type == SOCK_STREAM) /* See UNIX98 */ | ||
| 55 | return; | ||
| 51 | /* save primitive for use by the user. */ | 56 | /* save primitive for use by the user. */ |
| 52 | addr->sllc_family = skb->sk->sk_family; | 57 | addr = llc_ui_skb_cb(skb); |
| 58 | addr->sllc_family = sk->sk_family; | ||
| 53 | addr->sllc_arphrd = skb->dev->type; | 59 | addr->sllc_arphrd = skb->dev->type; |
| 54 | addr->sllc_test = prim == LLC_TEST_PRIM; | 60 | addr->sllc_test = prim == LLC_TEST_PRIM; |
| 55 | addr->sllc_xid = prim == LLC_XID_PRIM; | 61 | addr->sllc_xid = prim == LLC_XID_PRIM; |
| @@ -189,7 +195,7 @@ static void llc_sap_state_process(struct llc_sap *sap, struct sk_buff *skb) | |||
| 189 | if (skb->sk->sk_state == TCP_LISTEN) | 195 | if (skb->sk->sk_state == TCP_LISTEN) |
| 190 | kfree_skb(skb); | 196 | kfree_skb(skb); |
| 191 | else { | 197 | else { |
| 192 | llc_save_primitive(skb, ev->prim); | 198 | llc_save_primitive(skb->sk, skb, ev->prim); |
| 193 | 199 | ||
| 194 | /* queue skb to the user. */ | 200 | /* queue skb to the user. */ |
| 195 | if (sock_queue_rcv_skb(skb->sk, skb)) | 201 | if (sock_queue_rcv_skb(skb->sk, skb)) |
| @@ -308,7 +314,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb) | |||
| 308 | 314 | ||
| 309 | sk = llc_lookup_dgram(sap, &laddr); | 315 | sk = llc_lookup_dgram(sap, &laddr); |
| 310 | if (sk) { | 316 | if (sk) { |
| 311 | skb->sk = sk; | 317 | skb_set_owner_r(skb, sk); |
| 312 | llc_sap_rcv(sap, skb); | 318 | llc_sap_rcv(sap, skb); |
| 313 | sock_put(sk); | 319 | sock_put(sk); |
| 314 | } else | 320 | } else |
