linux-can.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Oliver Hartkopp <socketcan@hartkopp.net>
To: linux-can@vger.kernel.org,
	Mahesh.Maharjan-EXT@continental-corporation.com
Subject: Re: loopback  problem with BCM, RAW using,   Daniele Venzano
Date: Fri, 17 Aug 2012 14:13:57 +0200 (CEST)	[thread overview]
Message-ID: <1899121230.725766.1345205637801.JavaMail.open-xchange@webmail.strato.de> (raw)
In-Reply-To: <OF5F6ABAA1.C0168430-ONC1257A5D.003ADDEA-C1257A5D.003C4200@continental-corporation.com>

[-- Attachment #1: Type: text/plain, Size: 5637 bytes --]

Hello Mahesh,

i tried to generate a patch that allows you to disable the reception of local
generated CAN messages.

The patch is based on Kernel 3.6-rc2 - but it should be easy to backport by
hand.

Can you try it, if it solves your problem?

Maybe this extension to the CAN_RAW socket is useful for other people also ...

Regards,
Oliver

diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt
index 820f553..b6d28bd 100644
--- a/Documentation/networking/can.txt
+++ b/Documentation/networking/can.txt
@@ -23,7 +23,8 @@ This file contains
       4.1.3 RAW socket option CAN_RAW_LOOPBACK
       4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
       4.1.5 RAW socket option CAN_RAW_FD_FRAMES
-      4.1.6 RAW socket returned message flags
+      4.1.6 RAW socket option CAN_RAW_RECV_HOST_MSGS
+      4.1.7 RAW socket returned message flags
     4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
     4.3 connected transport protocols (SOCK_SEQPACKET)
     4.4 unconnected transport protocols (SOCK_DGRAM)
@@ -581,7 +582,23 @@ solution for a couple of reasons:
   CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU.
   The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.

-  4.1.6 RAW socket returned message flags
+  4.1.6 RAW socket option CAN_RAW_RECV_HOST_MSGS
+
+  When the local loopback is enabled, all the sent CAN frames are
+  looped back to the open CAN sockets that registered for the CAN
+  frames' CAN-ID on this given interface to meet the multi user
+  needs. The reception of the CAN frames originated from the local host
+  is therefore a wanted behaviour and enabled by default.
+
+  When the reception of locally generated CAN frames is not wanted, this
+  default behaviour may be changed on demand:
+
+    int recv_host_msgs = 0; /* 0 = disabled, 1 = enabled (default) */
+
+    setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_HOST_MSGS,
+               &recv_host_msgs, sizeof(recv_host_msgs));
+
+  4.1.7 RAW socket returned message flags

   When using recvmsg() call, the msg->msg_flags may contain following flags:

diff --git a/include/linux/can/raw.h b/include/linux/can/raw.h
index a814062..0d53fb6 100644
--- a/include/linux/can/raw.h
+++ b/include/linux/can/raw.h
@@ -25,6 +25,7 @@ enum {
        CAN_RAW_LOOPBACK,       /* local loopback (default:on)       */
        CAN_RAW_RECV_OWN_MSGS,  /* receive my own msgs (default:off) */
        CAN_RAW_FD_FRAMES,      /* allow CAN FD frames (default:off) */
+       CAN_RAW_RECV_HOST_MSGS, /* recv local host msgs (default:on) */
 };

 #endif
diff --git a/net/can/raw.c b/net/can/raw.c
index 3e9c893..0cfbc16 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -83,6 +83,7 @@ struct raw_sock {
        int loopback;
        int recv_own_msgs;
        int fd_frames;
+       int recv_host_msgs;
        int count;                 /* number of active filters */
        struct can_filter dfilter; /* default/single filter */
        struct can_filter *filter; /* pointer to filter(s) */
@@ -120,6 +121,10 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
        if (!ro->recv_own_msgs && oskb->sk == sk)
                return;

+       /* check if we need to skip locally generated messages */
+       if (!ro->recv_host_msgs && oskb->sk)
+               return;
+
        /* do not pass frames with DLC > 8 to a legacy socket */
        if (!ro->fd_frames) {
                struct canfd_frame *cfd = (struct canfd_frame *)oskb->data;
@@ -301,6 +306,7 @@ static int raw_init(struct sock *sk)
        ro->loopback         = 1;
        ro->recv_own_msgs    = 0;
        ro->fd_frames        = 0;
+       ro->recv_host_msgs   = 1;

        /* set notifier */
        ro->notifier.notifier_call = raw_notifier;
@@ -588,6 +594,15 @@ static int raw_setsockopt(struct socket *sock, int level,
int optname,

                break;

+       case CAN_RAW_RECV_HOST_MSGS:
+               if (optlen != sizeof(ro->recv_host_msgs))
+                       return -EINVAL;
+
+               if (copy_from_user(&ro->recv_host_msgs, optval, optlen))
+                       return -EFAULT;
+
+               break;
+
        default:
                return -ENOPROTOOPT;
        }
@@ -652,6 +667,12 @@ static int raw_getsockopt(struct socket *sock, int level,
int optname,
                val = &ro->fd_frames;
                break;

+       case CAN_RAW_RECV_HOST_MSGS:
+               if (len > sizeof(int))
+                       len = sizeof(int);
+               val = &ro->recv_host_msgs;
+               break;
+
        default:
                return -ENOPROTOOPT;
        }




Mahesh.Maharjan-EXT@continental-corporation.com hat am 17. August 2012 um 12:58
geschrieben:> hello to all,
> 
> Thanks to Oliver.  Suggesting for using both RAW n' BCM together .
>
> But As Already discussed by Daniele Venzano : The loopback problems  are
> occurring , When Sending can_message from BCM , RAW also  trying to read
> all message  dynamically. ( Suppose we don't need filter in system).And  I
> want to ignore all message  coming to same my node Again.  Even I used
> same  option  for setting "loopback mode"in raw socket.  But suggestion
> mention by Daniele. : can_send(skb, 1)  from bcm.c. Sound pretty simple.
> But doesn't look better to change directly from source code. Yeah , Even I
> changed for testing .. "no work done "....
>
> Help  !!!
>
>
> With Regards,
>
> Mahesh Maharjan
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: recv_hosts_msgs.patch --]
[-- Type: text/x-patch, Size: 3867 bytes --]

diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt
index 820f553..b6d28bd 100644
--- a/Documentation/networking/can.txt
+++ b/Documentation/networking/can.txt
@@ -23,7 +23,8 @@ This file contains
       4.1.3 RAW socket option CAN_RAW_LOOPBACK
       4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS
       4.1.5 RAW socket option CAN_RAW_FD_FRAMES
-      4.1.6 RAW socket returned message flags
+      4.1.6 RAW socket option CAN_RAW_RECV_HOST_MSGS
+      4.1.7 RAW socket returned message flags
     4.2 Broadcast Manager protocol sockets (SOCK_DGRAM)
     4.3 connected transport protocols (SOCK_SEQPACKET)
     4.4 unconnected transport protocols (SOCK_DGRAM)
@@ -581,7 +582,23 @@ solution for a couple of reasons:
   CAN FD frames by checking if the device maximum transfer unit is CANFD_MTU.
   The CAN device MTU can be retrieved e.g. with a SIOCGIFMTU ioctl() syscall.
 
-  4.1.6 RAW socket returned message flags
+  4.1.6 RAW socket option CAN_RAW_RECV_HOST_MSGS
+
+  When the local loopback is enabled, all the sent CAN frames are
+  looped back to the open CAN sockets that registered for the CAN
+  frames' CAN-ID on this given interface to meet the multi user
+  needs. The reception of the CAN frames originated from the local host
+  is therefore a wanted behaviour and enabled by default.
+
+  When the reception of locally generated CAN frames is not wanted, this
+  default behaviour may be changed on demand:
+
+    int recv_host_msgs = 0; /* 0 = disabled, 1 = enabled (default) */
+
+    setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_HOST_MSGS,
+               &recv_host_msgs, sizeof(recv_host_msgs));
+
+  4.1.7 RAW socket returned message flags
 
   When using recvmsg() call, the msg->msg_flags may contain following flags:
 
diff --git a/include/linux/can/raw.h b/include/linux/can/raw.h
index a814062..0d53fb6 100644
--- a/include/linux/can/raw.h
+++ b/include/linux/can/raw.h
@@ -25,6 +25,7 @@ enum {
 	CAN_RAW_LOOPBACK,	/* local loopback (default:on)       */
 	CAN_RAW_RECV_OWN_MSGS,	/* receive my own msgs (default:off) */
 	CAN_RAW_FD_FRAMES,	/* allow CAN FD frames (default:off) */
+	CAN_RAW_RECV_HOST_MSGS,	/* recv local host msgs (default:on) */
 };
 
 #endif
diff --git a/net/can/raw.c b/net/can/raw.c
index 3e9c893..0cfbc16 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -83,6 +83,7 @@ struct raw_sock {
 	int loopback;
 	int recv_own_msgs;
 	int fd_frames;
+	int recv_host_msgs;
 	int count;                 /* number of active filters */
 	struct can_filter dfilter; /* default/single filter */
 	struct can_filter *filter; /* pointer to filter(s) */
@@ -120,6 +121,10 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
 	if (!ro->recv_own_msgs && oskb->sk == sk)
 		return;
 
+	/* check if we need to skip locally generated messages */
+	if (!ro->recv_host_msgs && oskb->sk)
+		return;
+
 	/* do not pass frames with DLC > 8 to a legacy socket */
 	if (!ro->fd_frames) {
 		struct canfd_frame *cfd = (struct canfd_frame *)oskb->data;
@@ -301,6 +306,7 @@ static int raw_init(struct sock *sk)
 	ro->loopback         = 1;
 	ro->recv_own_msgs    = 0;
 	ro->fd_frames        = 0;
+	ro->recv_host_msgs   = 1;
 
 	/* set notifier */
 	ro->notifier.notifier_call = raw_notifier;
@@ -588,6 +594,15 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
 
 		break;
 
+	case CAN_RAW_RECV_HOST_MSGS:
+		if (optlen != sizeof(ro->recv_host_msgs))
+			return -EINVAL;
+
+		if (copy_from_user(&ro->recv_host_msgs, optval, optlen))
+			return -EFAULT;
+
+		break;
+
 	default:
 		return -ENOPROTOOPT;
 	}
@@ -652,6 +667,12 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
 		val = &ro->fd_frames;
 		break;
 
+	case CAN_RAW_RECV_HOST_MSGS:
+		if (len > sizeof(int))
+			len = sizeof(int);
+		val = &ro->recv_host_msgs;
+		break;
+
 	default:
 		return -ENOPROTOOPT;
 	}

  reply	other threads:[~2012-08-17 12:14 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-08-17 10:58 loopback problem with BCM, RAW using, Daniele Venzano Mahesh.Maharjan-EXT
2012-08-17 12:13 ` Oliver Hartkopp [this message]
2012-08-22  8:57   ` Kurt Van Dijck
2012-08-23  8:40     ` receiving CAN from remote hosts only Kurt Van Dijck
2012-08-23 18:35     ` loopback problem with BCM, RAW using, Daniele Venzano Oliver Hartkopp
2012-08-24  4:47       ` Kurt Van Dijck
2012-08-24  4:58         ` Oliver Hartkopp

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1899121230.725766.1345205637801.JavaMail.open-xchange@webmail.strato.de \
    --to=socketcan@hartkopp.net \
    --cc=Mahesh.Maharjan-EXT@continental-corporation.com \
    --cc=linux-can@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).