Re: [PATCH v1 1/2] j1939: add MSG_ERRQUEUE support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On do, 25 apr 2019 13:46:19 +0200, Oleksij Rempel wrote:
> Signed-off-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx>
> ---
>  include/uapi/linux/can/j1939.h |  6 +++++
>  net/can/j1939/j1939-priv.h     |  2 ++
>  net/can/j1939/socket.c         | 48 +++++++++++++++++++++++++++++++---
>  net/can/j1939/transport.c      | 33 ++++++++++++++++++++---
>  4 files changed, 83 insertions(+), 6 deletions(-)
> 
> diff --git a/include/uapi/linux/can/j1939.h b/include/uapi/linux/can/j1939.h
> index c7eb94d2ab10..77f8068bcc62 100644
> --- a/include/uapi/linux/can/j1939.h
> +++ b/include/uapi/linux/can/j1939.h
> @@ -72,6 +72,8 @@ enum {
>  	SCM_J1939_DEST_ADDR = 1,
>  	SCM_J1939_DEST_NAME = 2,
>  	SCM_J1939_PRIO = 3,
> +	SCM_J1939_RECVERR = 4,
> +	SCM_J1939_PKTINFO = 5,
>  };
>  
>  struct j1939_filter {
> @@ -83,6 +85,10 @@ struct j1939_filter {
>  	__u8 addr_mask;
>  };
>  
> +struct j1939_pktinfo {
> +	__u64 cookie;
> +};
> +
>  #define J1939_FILTER_MAX 512 /* maximum number of j1939_filter set via setsockopt() */
>  
>  #endif /* !_UAPI_CAN_J1939_H_ */
> diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h
> index 4cb2e63a86c4..cf42550de6d2 100644
> --- a/net/can/j1939/j1939-priv.h
> +++ b/net/can/j1939/j1939-priv.h
> @@ -207,6 +207,8 @@ struct j1939_session {
>  	bool transmission;
>  	bool extd;
>  	unsigned int total_message_size; /* Total message size, number of bytes */
> +	int err;
> +	u64 cookie;
>  
>  	/* Packets counters for a (extended) transfer session. The packet is
>  	 * maximal of 7 bytes. */
> diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
> index ea9ce6d99332..c88c67e93536 100644
> --- a/net/can/j1939/socket.c
> +++ b/net/can/j1939/socket.c
> @@ -608,6 +608,10 @@ static int j1939_sk_recvmsg(struct socket *sock, struct msghdr *msg,
>  	struct j1939_sk_buff_cb *skcb;
>  	int ret = 0;
>  
> +	if (flags & MSG_ERRQUEUE)
> +		return sock_recv_errqueue(sock->sk, msg, size, SOL_CAN_J1939,
> +					  SCM_J1939_RECVERR);
> +
>  	skb = skb_recv_datagram(sk, flags, 0, &ret);
>  	if (!skb)
>  		return ret;
> @@ -721,8 +725,9 @@ void j1939_sk_send_multi_abort(struct j1939_priv *priv, struct sock *sk,
>  	sk->sk_error_report(sk);
>  }
>  
> -static int j1939_sk_send_multi(struct j1939_priv *priv,  struct sock *sk,
> -			       struct msghdr *msg, size_t size)
> +static int j1939_sk_send_multi(struct j1939_priv *priv, struct sock *sk,
> +			       struct msghdr *msg, size_t size,
> +			       struct j1939_pktinfo *info)
>  
>  {
>  	struct j1939_sock *jsk = j1939_sk(sk);
> @@ -788,6 +793,7 @@ static int j1939_sk_send_multi(struct j1939_priv *priv,  struct sock *sk,
>  					ret = PTR_ERR(session);
>  					goto kfree_skb;
>  				}
> +				session->cookie = info->cookie;
>  			}
>  		} else {
>  			j1939_session_skb_queue(session, skb);
> @@ -845,6 +851,35 @@ static int j1939_sk_send_one(struct j1939_priv *priv,  struct sock *sk,
>  	return ret ? ret : size;
>  }
>  
> +static int j1939_sk_cmsg_send(struct sock *sk, struct msghdr *msg,
> +			      struct j1939_pktinfo *info)
> +{
> +	struct cmsghdr *cmsg;
> +
> +	for_each_cmsghdr(cmsg, msg) {
> +		if (!CMSG_OK(msg, cmsg))
> +			return -EINVAL;
> +
> +		if (cmsg->cmsg_level != SOL_CAN_J1939)
> +			continue;
> +		switch (cmsg->cmsg_type) {
> +		case SCM_J1939_PKTINFO:
> +		{
> +			struct j1939_pktinfo *tinfo;
> +
> +			if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct j1939_pktinfo)))
> +				return -EINVAL;
> +			tinfo = (struct j1939_pktinfo *)CMSG_DATA(cmsg);
> +			memcpy(info, tinfo, sizeof(*info));
> +			break;
> +		}
> +		default:
> +			return -EINVAL;
> +		}
> +	}
> +	return 0;
> +}
> +
>  static int j1939_sk_sendmsg(struct socket *sock, struct msghdr *msg,
>  			    size_t size)
>  {
> @@ -852,6 +887,7 @@ static int j1939_sk_sendmsg(struct socket *sock, struct msghdr *msg,
>  	struct j1939_sock *jsk = j1939_sk(sk);
>  	struct j1939_priv *priv;
>  	struct net_device *ndev;
> +	struct j1939_pktinfo info;

info is initialized only when msg_controllen is set.
This is not necessarily always the case?




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux