/* * This is where all X.25 information frames pass. * * Returns the amount of user data bytes sent on success * or a negative error code on failure. */ int x25_output(struct sock *sk, struct sk_buff *skb) { struct sk_buff *skbn; unsigned char header[X25_EXT_MIN_LEN]; int err, frontlen, len, header_len, max_len; int sent=0, noblock = X25_SKB_CB(skb)->flags & MSG_DONTWAIT; header_len = (sk->protinfo.x25->neighbour->extended) ? X25_EXT_MIN_LEN : X25_STD_MIN_LEN; max_len = x25_pacsize_to_bytes(sk->protinfo.x25->facilities.pacsize_out); if (skb->len - header_len > max_len) { /* Save a copy of the Header */ memcpy(header, skb->data, header_len); skb_pull(skb, header_len); frontlen = skb_headroom(skb); while (skb->len > 0) { if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len, noblock, &err)) == NULL){ if(err == -EWOULDBLOCK && noblock){ kfree_skb(skb); return sent; } SOCK_DEBUG(sk, "x25_output: fragment allocation failed, err=%d, %d bytes sent\n", err, sent); return err; } skb_reserve(skbn, frontlen); len = (max_len > skb->len) ? skb->len : max_len; /* Copy the user data */ memcpy(skb_put(skbn, len), skb->data, len); skb_pull(skb, len); /* Duplicate the Header */ skb_push(skbn, header_len); memcpy(skbn->data, header, header_len); if (skb->len > 0) { if (sk->protinfo.x25->neighbour->extended) skbn->data[3] |= X25_EXT_M_BIT; else skbn->data[2] |= X25_STD_M_BIT; } skb_queue_tail(&sk->write_queue, skbn); sent += len; } kfree_skb(skb); } else { skb_queue_tail(&sk->write_queue, skb); sent = skb->len - header_len; } return sent; }
/* * This is where all X.25 information frames pass. * * Returns the amount of user data bytes sent on success * or a negative error code on failure. */ int x25_output(struct sock *sk, struct sk_buff *skb) { struct sk_buff *skbn; unsigned char header[X25_EXT_MIN_LEN]; int err, frontlen, len; int sent=0, noblock = X25_SKB_CB(skb)->flags & MSG_DONTWAIT; struct x25_sock *x25 = x25_sk(sk); int header_len = x25->neighbour->extended ? X25_EXT_MIN_LEN : X25_STD_MIN_LEN; int max_len = x25_pacsize_to_bytes(x25->facilities.pacsize_out); if (skb->len - header_len > max_len) { /* Save a copy of the Header */ skb_copy_from_linear_data(skb, header, header_len); skb_pull(skb, header_len); frontlen = skb_headroom(skb); while (skb->len > 0) { <<<<<<< HEAD release_sock(sk); skbn = sock_alloc_send_skb(sk, frontlen + max_len, noblock, &err); lock_sock(sk); if (!skbn) { ======= if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len, noblock, &err)) == NULL){ >>>>>>> 296c66da8a02d52243f45b80521febece5ed498a if (err == -EWOULDBLOCK && noblock){ kfree_skb(skb); return sent; } SOCK_DEBUG(sk, "x25_output: fragment alloc" " failed, err=%d, %d bytes " "sent\n", err, sent); return err; }
/* * This is where all X.25 information frames pass. * * Returns the amount of user data bytes sent on success * or a negative error code on failure. */ int x25_output(struct sock *sk, struct sk_buff *skb) { struct sk_buff *skbn; unsigned char header[X25_EXT_MIN_LEN]; int err, frontlen, len; int sent=0, noblock = X25_SKB_CB(skb)->flags & MSG_DONTWAIT; struct x25_sock *x25 = x25_sk(sk); int header_len = x25->neighbour->extended ? X25_EXT_MIN_LEN : X25_STD_MIN_LEN; int max_len = x25_pacsize_to_bytes(x25->facilities.pacsize_out); if (skb->len - header_len > max_len) { /* Save a copy of the Header */ skb_copy_from_linear_data(skb, header, header_len); skb_pull(skb, header_len); frontlen = skb_headroom(skb); while (skb->len > 0) { release_sock(sk); skbn = sock_alloc_send_skb(sk, frontlen + max_len, noblock, &err); lock_sock(sk); if (!skbn) { if (err == -EWOULDBLOCK && noblock){ kfree_skb(skb); return sent; } SOCK_DEBUG(sk, "x25_output: fragment alloc" " failed, err=%d, %d bytes " "sent\n", err, sent); return err; } skb_reserve(skbn, frontlen); len = max_len > skb->len ? skb->len : max_len; /* Copy the user data */ skb_copy_from_linear_data(skb, skb_put(skbn, len), len); skb_pull(skb, len); /* Duplicate the Header */ skb_push(skbn, header_len); skb_copy_to_linear_data(skbn, header, header_len); if (skb->len > 0) { if (x25->neighbour->extended) skbn->data[3] |= X25_EXT_M_BIT; else skbn->data[2] |= X25_STD_M_BIT; } skb_queue_tail(&sk->sk_write_queue, skbn); sent += len; } kfree_skb(skb); } else { skb_queue_tail(&sk->sk_write_queue, skb); sent = skb->len - header_len; } return sent; }