diff options
Diffstat (limited to 'net/llc')
-rw-r--r-- | net/llc/af_llc.c | 20 | ||||
-rw-r--r-- | net/llc/llc_core.c | 3 | ||||
-rw-r--r-- | net/llc/llc_sap.c | 7 |
3 files changed, 14 insertions, 16 deletions
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index d6cfe84d521..2652ead96c6 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -784,24 +784,20 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, copied += used; len -= used; - if (used + offset < skb->len) - continue; - if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, 0); *seq = 0; } + + /* For non stream protcols we get one packet per recvmsg call */ + if (sk->sk_type != SOCK_STREAM) + goto copy_uaddr; + + /* Partial read */ + if (used + offset < skb->len) + continue; } while (len > 0); - /* - * According to UNIX98, msg_name/msg_namelen are ignored - * on connected socket. -ANK - * But... af_llc still doesn't have separate sets of methods for - * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will - * eventually fix this tho :-) -acme - */ - if (sk->sk_type == SOCK_DGRAM) - goto copy_uaddr; out: release_sock(sk); return copied; diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index bd242a49514..d12413cff5b 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c @@ -33,10 +33,9 @@ unsigned char llc_station_mac_sa[ETH_ALEN]; */ static struct llc_sap *llc_sap_alloc(void) { - struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC); + struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); if (sap) { - memset(sap, 0, sizeof(*sap)); sap->state = LLC_SAP_STATE_ACTIVE; memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); rwlock_init(&sap->sk_list.lock); diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index 20c4eb5c1ac..61cb8cf7d15 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -51,10 +51,10 @@ void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim) { struct sockaddr_llc *addr; - if (skb->sk->sk_type == SOCK_STREAM) /* See UNIX98 */ - return; /* save primitive for use by the user. */ addr = llc_ui_skb_cb(skb); + + memset(addr, 0, sizeof(*addr)); addr->sllc_family = sk->sk_family; addr->sllc_arphrd = skb->dev->type; addr->sllc_test = prim == LLC_TEST_PRIM; @@ -330,6 +330,9 @@ static void llc_sap_mcast(struct llc_sap *sap, if (llc->laddr.lsap != laddr->lsap) continue; + if (llc->dev != skb->dev) + continue; + skb1 = skb_clone(skb, GFP_ATOMIC); if (!skb1) break; |