Re: Linux Socket-Can Filters Not Working on Startup

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

 



Hi Tom,

On 12/21/18 5:52 AM, Tom Evans wrote:
We've just found the cause of an intermittent CAN problem. It may be instructive to others.

Our CAN code looks something like:

1)    int skt = socket( PF_CAN, SOCK_RAW | SOCK_NONBLOCK, CAN_RAW );
       ...
2)    int rc=ioctl(skt, SIOCGIFINDEX, &ifr); /* ifr.ifr_ifindex filled ... */
       ...
3)    rc = bind(skt, (struct sockaddr*)&addr, sizeof(addr));

Here you introduce the problem :-)

       ...
4)    rc = setsockopt(skt, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter,
                       sizeof(rfilter));
       ...
5)    rc = recv(skt, &frame, sizeof(frame), MSG_DONTWAIT);

The Receive path assumes the Filter that was applied to the socket is working.

That was a rookie mistake. It isn't.

We're receiving all sorts of garbage on the first few reads of the socket. Messages that are being misinterpreted to make very bright warning lights flash in all sorts of worrying and unexpected ways.

This is because the thread performing the above can get suspended between when the socket is bound at (3), and when the filter is applied at (4).

You are just using the wrong order on the syscalls!

When you created a socket you *first* apply the filters and other options by setsockopt() and *then* bind the socket.

An example:
https://github.com/linux-can/can-utils/blob/master/cansend.c#L134

You can find that in candump.c too - but it's harder to find ;-)

It is also possible to change the filters on a bound socket - but you always have to cope with some fall-out then.

When you bind the socket without setting a filter you get the default filter == everything passes. Which finally creates the fall-out until you set the new filter in your example above.

And during this time it is WIDE OPEN and will receive every message on the CAN bus, every ID, Standard and Extended.

Just swap bind() & setsockopt() and you get what you wanted.

Have fun,
Oliver




[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