}
ssk = swift_sk(sock->sk);
+ sock->sk->sk_rcvbuf = 10 * 1024 * 1024;
ssk->src = port;
swift_hash(port, ssk);
for (i = 0; i < dests; i++) {
struct swift_dest *dest = &swift_addr->dests[i];
struct iovec *iov = &msg->msg_iov[i];
+ char *payload;
dport = dest->port;
if (unlikely(dport == 0 || dport >= MAX_SWIFT_PORT)) {
shdr->src = sport;
shdr->len = ntohs(len + sizeof(struct swifthdr));
- log_debug("payload=%p\n", skb_put(skb, len));
+ payload = skb_put(skb, len);
+ log_debug("payload=%p\n", payload);
err = skb_copy_datagram_from_iovec(skb, sizeof(struct swifthdr), iov, 0, len);
if (unlikely(err)) {
#endif
}
+ skb->local_df = 1;
err = ip_queue_xmit(skb);
if (likely(!err))
log_debug("Sent %u bytes on wire\n", len);
struct sockaddr_swift *swift_addr;
struct sock * sk = sock->sk;
int err, copied;
+ int i;
+ struct sockaddr_swift *ret_addr = (struct sockaddr_swift *) msg->msg_name;
log_debug("Trying to receive sock=%p sk=%p flags=%d\n", sock, sk, flags);
goto out;
}
- log_debug("Received skb %p\n", skb);
+ for (i = 0; i < msg->msg_iovlen; i++) {
+ log_debug("Received skb %p\n", skb);
- swift_addr = (struct sockaddr_swift *) skb->cb;
- msg->msg_namelen = sizeof(struct sockaddr_swift);
+ swift_addr = (struct sockaddr_swift *) skb->cb;
- copied = skb->len;
- if (copied > len) {
- copied = len;
- msg->msg_flags |= MSG_TRUNC;
- }
+ copied = skb->len;
+ if (copied > msg->msg_iov[i].iov_len) {
+ copied = msg->msg_iov[i].iov_len;
+ msg->msg_flags |= MSG_TRUNC;
+ }
- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
- if (unlikely(err)) {
- log_error("skb_copy_datagram_iovec\n");
- goto out_free;
- }
+ err = skb_copy_datagram_iovec(skb, 0, &msg->msg_iov[i], copied);
+ if (unlikely(err)) {
+ log_error("skb_copy_datagram_iovec\n");
+ goto out_free;
+ }
+ log_debug("Received %d bytes\n", copied);
- sock_recv_ts_and_drops(msg, sk, skb);
+ sock_recv_ts_and_drops(msg, sk, skb);
- if (msg->msg_name)
- memcpy(msg->msg_name, swift_addr, msg->msg_namelen);
-
- err = copied;
+ if (ret_addr) {
+ memcpy(&ret_addr->dests[i], &mptp_addr->dests[0], sizeof(ret_addr->dests[i]));
+ ret_addr->dests[i].bytes = copied;
+ }
+
+ err = copied;
out_free:
- skb_free_datagram(sk, skb);
+ skb_free_datagram(sk, skb);
+
+ skb = skb_recv_datagram(sk, flags, 1, &err);
+ if (likely(err == -EAGAIN)) {
+ log_debug("No more skbs in the queue, returning...\n");
+ err = copied;
+ break;
+ }
+ }
+
+ ret_addr->count = i + 1;
+ msg->msg_namelen = sizeof(struct sockaddr_swift) + (i + 1) * sizeof(struct swift_dest);
out:
return err;
uint8_t src, dst;
struct sockaddr_swift * swift_addr;
int err;
+ int addr_size = sizeof(struct sockaddr_swift) + sizeof(struct swift_dest);
if (unlikely(!pskb_may_pull(skb, sizeof(struct swifthdr)))) {
log_error("Insufficient space for header\n");
goto drop;
}
- BUILD_BUG_ON(sizeof(struct sockaddr_swift) > sizeof(skb->cb));
+ BUG_ON(addr_size > sizeof(skb->cb));
swift_addr = (struct sockaddr_swift *) skb->cb;
swift_addr->dests[0].port = shdr->src;
err = ip_queue_rcv_skb((struct sock *) &ssk->sock, skb);
if (unlikely(err)) {
- log_error("ip_queu_rcv_skb\n");
+ log_error("ip_queue_rcv_skb failed with %d\n", err);
consume_skb(skb);
}
return NET_RX_SUCCESS;