X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=net%2Fiucv%2Faf_iucv.c;h=09e1694b6d341a5f1cf81e49643f9267ac4033c4;hb=06996c1d4088a0d5f3e7789d7f96b4653cc947cc;hp=36eb8d1d912849b732f4410e34556cd56a0c06ef;hpb=01047631df813f6247185547c3778c80af088a20;p=thirdparty%2Fkernel%2Fstable.git diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 36eb8d1d91284..09e1694b6d341 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -14,6 +14,7 @@ #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt #include +#include #include #include #include @@ -347,14 +348,14 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock, if (imsg) memcpy(&phs_hdr->iucv_hdr, imsg, sizeof(struct iucv_message)); - skb_push(skb, ETH_HLEN); - memset(skb->data, 0, ETH_HLEN); - skb->dev = iucv->hs_dev; if (!skb->dev) { err = -ENODEV; goto err_free; } + + dev_hard_header(skb, skb->dev, ETH_P_AF_IUCV, NULL, NULL, skb->len); + if (!(skb->dev->flags & IFF_UP) || !netif_carrier_ok(skb->dev)) { err = -ENETDOWN; goto err_free; @@ -367,6 +368,8 @@ static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock, skb_trim(skb, skb->dev->mtu); } skb->protocol = cpu_to_be16(ETH_P_AF_IUCV); + + __skb_header_release(skb); nskb = skb_clone(skb, GFP_ATOMIC); if (!nskb) { err = -ENOMEM; @@ -466,12 +469,14 @@ static void iucv_sever_path(struct sock *sk, int with_user_data) /* Send controlling flags through an IUCV socket for HIPER transport */ static int iucv_send_ctrl(struct sock *sk, u8 flags) { + struct iucv_sock *iucv = iucv_sk(sk); int err = 0; int blen; struct sk_buff *skb; u8 shutdown = 0; - blen = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN; + blen = sizeof(struct af_iucv_trans_hdr) + + LL_RESERVED_SPACE(iucv->hs_dev); if (sk->sk_shutdown & SEND_SHUTDOWN) { /* controlling flags should be sent anyway */ shutdown = sk->sk_shutdown; @@ -588,7 +593,6 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio, sk->sk_destruct = iucv_sock_destruct; sk->sk_sndtimeo = IUCV_CONN_TIMEOUT; - sk->sk_allocation = GFP_DMA; sock_reset_flag(sk, SOCK_ZAPPED); @@ -782,6 +786,7 @@ vm_bind: memcpy(iucv->src_user_id, iucv_userid, 8); sk->sk_state = IUCV_BOUND; iucv->transport = AF_IUCV_TRANS_IUCV; + sk->sk_allocation |= GFP_DMA; if (!iucv->msglimit) iucv->msglimit = IUCV_QUEUELEN_DEFAULT; goto done_unlock; @@ -806,6 +811,8 @@ static int iucv_sock_autobind(struct sock *sk) return -EPROTO; memcpy(iucv->src_user_id, iucv_userid, 8); + iucv->transport = AF_IUCV_TRANS_IUCV; + sk->sk_allocation |= GFP_DMA; write_lock_bh(&iucv_sk_list.lock); __iucv_auto_name(iucv); @@ -1131,7 +1138,8 @@ static int iucv_sock_sendmsg(struct socket *sock, struct msghdr *msg, * segmented records using the MSG_EOR flag), but * for SOCK_STREAM we might want to improve it in future */ if (iucv->transport == AF_IUCV_TRANS_HIPER) { - headroom = sizeof(struct af_iucv_trans_hdr) + ETH_HLEN; + headroom = sizeof(struct af_iucv_trans_hdr) + + LL_RESERVED_SPACE(iucv->hs_dev); linear = len; } else { if (len < PAGE_SIZE) { @@ -1781,6 +1789,8 @@ static int iucv_callback_connreq(struct iucv_path *path, niucv = iucv_sk(nsk); iucv_sock_init(nsk, sk); + niucv->transport = AF_IUCV_TRANS_IUCV; + nsk->sk_allocation |= GFP_DMA; /* Set the new iucv_sock */ memcpy(niucv->dst_name, ipuser + 8, 8); @@ -2430,6 +2440,13 @@ out: return err; } +static void afiucv_iucv_exit(void) +{ + device_unregister(af_iucv_dev); + driver_unregister(&af_iucv_driver); + pr_iucv->iucv_unregister(&af_iucv_handler, 0); +} + static int __init afiucv_init(void) { int err; @@ -2463,11 +2480,18 @@ static int __init afiucv_init(void) err = afiucv_iucv_init(); if (err) goto out_sock; - } else - register_netdevice_notifier(&afiucv_netdev_notifier); + } + + err = register_netdevice_notifier(&afiucv_netdev_notifier); + if (err) + goto out_notifier; + dev_add_pack(&iucv_packet_type); return 0; +out_notifier: + if (pr_iucv) + afiucv_iucv_exit(); out_sock: sock_unregister(PF_IUCV); out_proto: @@ -2481,12 +2505,11 @@ out: static void __exit afiucv_exit(void) { if (pr_iucv) { - device_unregister(af_iucv_dev); - driver_unregister(&af_iucv_driver); - pr_iucv->iucv_unregister(&af_iucv_handler, 0); + afiucv_iucv_exit(); symbol_put(iucv_if); - } else - unregister_netdevice_notifier(&afiucv_netdev_notifier); + } + + unregister_netdevice_notifier(&afiucv_netdev_notifier); dev_remove_pack(&iucv_packet_type); sock_unregister(PF_IUCV); proto_unregister(&iucv_proto);