--- zzzz-none-000/linux-3.10.107/net/atm/common.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/net/atm/common.c 2021-02-04 17:41:59.000000000 +0000 @@ -141,7 +141,29 @@ .release_cb = vcc_release_cb, }; -int vcc_create(struct net *net, struct socket *sock, int protocol, int family) +#ifdef CONFIG_LTQ_OAM +int (*push_oam_pfn)(struct atm_vcc *atmvcc, void *cell) = NULL; +EXPORT_SYMBOL(push_oam_pfn); + +int ifx_push_oam(struct atm_vcc *atmvcc, void *cell) +{ + if (push_oam_pfn != NULL) + return push_oam_pfn(atmvcc, cell); + return -1; +} +EXPORT_SYMBOL(ifx_push_oam); +#endif + +#if defined(CONFIG_VRX318_DATAPATH) || defined(CONFIG_VRX318_DATAPATH_MODULE) || \ + defined(CONFIG_VRX518_TC) || defined(CONFIG_VRX518_TC_MODULE) || IS_ENABLED(CONFIG_VRX518) +void (*atm_hook_mpoa_setup)(struct atm_vcc *, int, int, struct net_device *) = NULL; +EXPORT_SYMBOL(atm_hook_mpoa_setup); +#else +void (*ppa_hook_mpoa_setup)(struct atm_vcc *, int, int) = NULL; +EXPORT_SYMBOL(ppa_hook_mpoa_setup); +#endif + +int vcc_create(struct net *net, struct socket *sock, int protocol, int family, int kern) { struct sock *sk; struct atm_vcc *vcc; @@ -149,7 +171,7 @@ sock->sk = NULL; if (sock->type == SOCK_STREAM) return -EINVAL; - sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto); + sk = sk_alloc(net, family, GFP_KERNEL, &vcc_proto, kern); if (!sk) return -ENOMEM; sock_init_data(sock, sk); @@ -165,8 +187,11 @@ atomic_set(&sk->sk_rmem_alloc, 0); vcc->push = NULL; vcc->pop = NULL; - vcc->owner = NULL; +#ifdef CONFIG_LTQ_OAM + vcc->push_oam = ifx_push_oam; +#else vcc->push_oam = NULL; +#endif vcc->release_cb = NULL; vcc->vpi = vcc->vci = 0; /* no VCI/VPI yet */ vcc->atm_options = vcc->aal_options = 0; @@ -300,7 +325,7 @@ max_sdu = ATM_MAX_AAL34_PDU; break; default: - pr_warning("AAL problems ... (%d)\n", aal); + pr_warn("AAL problems ... (%d)\n", aal); /* fall through */ case ATM_AAL5: max_sdu = ATM_MAX_AAL5_PDU; @@ -523,8 +548,8 @@ return 0; } -int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, - size_t size, int flags) +int vcc_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, + int flags) { struct sock *sk = sock->sk; struct atm_vcc *vcc; @@ -554,7 +579,7 @@ msg->msg_flags |= MSG_TRUNC; } - error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); + error = skb_copy_datagram_msg(skb, 0, msg, copied); if (error) return error; sock_recv_ts_and_drops(msg, sk, skb); @@ -569,16 +594,13 @@ return copied; } -int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m, - size_t total_len) +int vcc_sendmsg(struct socket *sock, struct msghdr *m, size_t size) { struct sock *sk = sock->sk; DEFINE_WAIT(wait); struct atm_vcc *vcc; struct sk_buff *skb; int eff, error; - const void __user *buff; - int size; lock_sock(sk); if (sock->state != SS_CONNECTED) { @@ -589,12 +611,6 @@ error = -EISCONN; goto out; } - if (m->msg_iovlen != 1) { - error = -ENOSYS; /* fix this later @@@ */ - goto out; - } - buff = m->msg_iov->iov_base; - size = m->msg_iov->iov_len; vcc = ATM_SD(sock); if (test_bit(ATM_VF_RELEASED, &vcc->flags) || test_bit(ATM_VF_CLOSE, &vcc->flags) || @@ -607,7 +623,7 @@ error = 0; goto out; } - if (size < 0 || size > vcc->qos.txtp.max_sdu) { + if (size > vcc->qos.txtp.max_sdu) { error = -EMSGSIZE; goto out; } @@ -639,7 +655,7 @@ goto out; skb->dev = NULL; /* for paths shared with net_device interfaces */ ATM_SKB(skb)->atm_options = vcc->atm_options; - if (copy_from_user(skb_put(skb, size), buff, size)) { + if (copy_from_iter(skb_put(skb, size), size, &m->msg_iter) != size) { kfree_skb(skb); error = -EFAULT; goto out;