/** * Fill in the msg ancillary data buffer with all control messages * according to cmsg_flags the user has set beforehand. */ void ci_ip_cmsg_recv(ci_netif* ni, ci_udp_state* us, const ci_ip_pkt_fmt *pkt, struct msghdr *msg, int netif_locked) { unsigned flags = us->s.cmsg_flags; struct cmsg_state cmsg_state; cmsg_state.msg = msg; cmsg_state.cmsg_bytes_used = 0; cmsg_state.cm = CMSG_FIRSTHDR(msg); if( pkt->flags & CI_PKT_FLAG_RX_INDIRECT ) pkt = PKT_CHK_NML(ni, pkt->frag_next, netif_locked); if (flags & CI_IP_CMSG_PKTINFO) { ++us->stats.n_rx_pktinfo; ip_cmsg_recv_pktinfo(ni, pkt, &cmsg_state); } if (flags & CI_IP_CMSG_TTL) ip_cmsg_recv_ttl(pkt, &cmsg_state); if (flags & CI_IP_CMSG_TOS) ip_cmsg_recv_tos(pkt, &cmsg_state); if( flags & CI_IP_CMSG_TIMESTAMPNS ) ip_cmsg_recv_timestampns(ni, pkt->pf.udp.rx_stamp, &cmsg_state); else /* SO_TIMESTAMP gets ignored when SO_TIMESTAMPNS one is set */ if( flags & CI_IP_CMSG_TIMESTAMP ) ip_cmsg_recv_timestamp(ni, pkt->pf.udp.rx_stamp, &cmsg_state); if( flags & CI_IP_CMSG_TIMESTAMPING ) { int flags = us->s.timestamping_flags; if( flags & (ONLOAD_SOF_TIMESTAMPING_RAW_HARDWARE | ONLOAD_SOF_TIMESTAMPING_SYS_HARDWARE | ONLOAD_SOF_TIMESTAMPING_SOFTWARE) ) { struct timespec rx_hw_stamp; rx_hw_stamp.tv_sec = pkt->pf.udp.rx_hw_stamp.tv_sec; rx_hw_stamp.tv_nsec = pkt->pf.udp.rx_hw_stamp.tv_nsec; if( ! (rx_hw_stamp.tv_nsec & CI_IP_PKT_HW_STAMP_FLAG_IN_SYNC) ) flags &= ~ONLOAD_SOF_TIMESTAMPING_SYS_HARDWARE; ip_cmsg_recv_timestamping(ni, pkt->pf.udp.rx_stamp, &rx_hw_stamp, flags, &cmsg_state); } } ci_ip_cmsg_finish(&cmsg_state); }
void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) { struct inet_sock *inet = inet_sk(skb->sk); unsigned flags = inet->cmsg_flags; /* Ordered by supposed usage frequency */ if (flags & IP_CMSG_PKTINFO) { ip_cmsg_recv_pktinfo(msg, skb); flags &= ~IP_CMSG_PKTINFO; if (!flags) return; } if (flags & IP_CMSG_TTL) { ip_cmsg_recv_ttl(msg, skb); flags &= ~IP_CMSG_TTL; if (!flags) return; } if (flags & IP_CMSG_TOS) { ip_cmsg_recv_tos(msg, skb); flags &= ~IP_CMSG_TOS; if (!flags) return; } if (flags & IP_CMSG_RECVOPTS) { ip_cmsg_recv_opts(msg, skb); flags &= ~IP_CMSG_RECVOPTS; if (!flags) return; } if (flags & IP_CMSG_RETOPTS) { ip_cmsg_recv_retopts(msg, skb); flags &= ~IP_CMSG_RETOPTS; if (!flags) return; } if (flags & IP_CMSG_PASSSEC) { ip_cmsg_recv_security(msg, skb); flags &= ~IP_CMSG_PASSSEC; if (!flags) return; } if (flags & IP_CMSG_ORIGDSTADDR) ip_cmsg_recv_dstaddr(msg, skb); }
void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, struct sk_buff *skb, int tlen, int offset) { struct inet_sock *inet = inet_sk(sk); unsigned int flags = inet->cmsg_flags; /* Ordered by supposed usage frequency */ if (flags & IP_CMSG_PKTINFO) { ip_cmsg_recv_pktinfo(msg, skb); flags &= ~IP_CMSG_PKTINFO; if (!flags) return; } if (flags & IP_CMSG_TTL) { ip_cmsg_recv_ttl(msg, skb); flags &= ~IP_CMSG_TTL; if (!flags) return; } if (flags & IP_CMSG_TOS) { ip_cmsg_recv_tos(msg, skb); flags &= ~IP_CMSG_TOS; if (!flags) return; } if (flags & IP_CMSG_RECVOPTS) { ip_cmsg_recv_opts(msg, skb); flags &= ~IP_CMSG_RECVOPTS; if (!flags) return; } if (flags & IP_CMSG_RETOPTS) { ip_cmsg_recv_retopts(msg, skb); flags &= ~IP_CMSG_RETOPTS; if (!flags) return; } if (flags & IP_CMSG_PASSSEC) { ip_cmsg_recv_security(msg, skb); flags &= ~IP_CMSG_PASSSEC; if (!flags) return; } if (flags & IP_CMSG_ORIGDSTADDR) { ip_cmsg_recv_dstaddr(msg, skb); flags &= ~IP_CMSG_ORIGDSTADDR; if (!flags) return; } if (flags & IP_CMSG_CHECKSUM) ip_cmsg_recv_checksum(msg, skb, tlen, offset); if (flags & IP_CMSG_RECVFRAGSIZE) ip_cmsg_recv_fragsize(msg, skb); }