Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Any write to CAN_BCM socket returns -1 with errno = 22 #505

Open
JuraszekL opened this issue Mar 16, 2024 · 7 comments
Open

Any write to CAN_BCM socket returns -1 with errno = 22 #505

JuraszekL opened this issue Mar 16, 2024 · 7 comments

Comments

@JuraszekL
Copy link

Hi guys!
I am just a beginner so please, be patient to my ineptitude.

I was trying to write simple code to test BCM sockets, but anytime i want to add some new rule, the write function returns an error and errno is set to 22. I decided then to run bcmserver and add rule through a socket, but the results are the same. Here are the details:

I am using RaspberryPi 4 with CAN FD shield.

juraszekl@raspberrypi:~ $ uname -a 
Linux raspberrypi 6.1.0-rpi8-rpi-v8 #1 SMP PREEMPT Debian 1:6.1.73-1+rpt1 (2024-01-25) aarch64 GNU/Linux

First, simple configuration of interface:

juraszekl@raspberrypi:~ $ sudo ip link set can0 up type can bitrate 100000

Next loading can_bcm module:

juraszekl@raspberrypi:~ $ sudo modprobe can-bcm
juraszekl@raspberrypi:~ $ sudo lsmod | grep can
can_bcm                24576  0
can                    28672  1 can_bcm
can_dev                40960  1 mcp251xfd

I've add a few printf's to the original bcmserver.c file, then recompiled. if i send the command:

juraszekl@raspberrypi:~ $ echo "< can0 A 1 0 123 8 11 22 33 44 55 66 77 88 >" | nc 0.0.0.0 28600

the output from bcmserver is:

juraszekl@raspberrypi:~/Temp/can-utils $ ./bcmserver 
listening
forking
BCM socket opened, sc = 5
BCM socket connected
read '< can0 A 1 0 123 8 11 22 33 44 55 66 77 88 >'
sscanf ok! items = 14
res = -1, errno = 22

code that gives the last line looks like this:

if (!ioctl(sc, SIOCGIFINDEX, &ifr)) {
	caddr.can_ifindex = ifr.ifr_ifindex;
	res = sendto(sc, &msg, sizeof(msg), 0,
			(struct sockaddr*)&caddr, sizeof(caddr));
        printf("res = %d, errno = %d\n", res, errno);
        }

After two days and many different combinations with msg structure, interface numbers and socket options i must give up.

Please tell me what am i doing wrong.

BR.
Łukasz

@hartkopp
Copy link
Member

Hi Łukasz,

I tried your exact setup with a virtual CAN interface "vcan0"
echo "< vcan0 A 1 0 123 8 11 22 33 44 55 66 77 88 >" | nc 0.0.0.0 28600

and it works as expected:

$ candump any -td
 (000.000000)  vcan0  123   [8]  11 22 33 44 55 66 77 88
 (001.000135)  vcan0  123   [8]  11 22 33 44 55 66 77 88
 (001.000146)  vcan0  123   [8]  11 22 33 44 55 66 77 88
...

Maybe there's something wrong with your can0 interface?!?

Can you please check if your system runs fine with a virtual CAN interface?

@hartkopp
Copy link
Member

hartkopp commented Mar 16, 2024

I have another idea what might be wrong.

juraszekl@raspberrypi:~ $ uname -a 
Linux raspberrypi 6.1.0-rpi8-rpi-v8 #1 SMP PREEMPT Debian 1:6.1.73-1+rpt1 (2024-01-25) aarch64 GNU/Linux

Can you please check whether the bcmserver is a 64 bit binary too?

E.g. with file bcmserver
On my 64 bit X86 it looks like this:

$ file bcmserver
bcmserver: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=eee7e8c285a5dbdb9c0b6bfcf3ceb5f29667fcca, for GNU/Linux 3.2.0, not stripped

@JuraszekL
Copy link
Author

Can you please check if your system runs fine with a virtual CAN interface?

So, i have both modules:

$ lsmod | grep can
can_bcm                24576  0
can                    28672  1 can_bcm
vcan                   16384  0
can_dev                40960  2 mcp251xfd,vcan

and operating vcan0:

$ sudo ip link add dev vcan0 type vcan
$ sudo ip link set vcan0 up
$ ip link show vcan0
6: vcan0: <NOARP,UP,LOWER_UP> mtu 72 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/can 

but output is the same:

$ ./bcmserver 
listening
forking
BCM socket opened, sc = 5
BCM socket connected
read '< vcan0 A 1 0 123 8 11 22 33 44 55 66 77 88 >'
sscanf ok! items = 14
res = -1, errno = 22

Can you please check whether the bcmserver is a 64 bit binary too?

Bingo!

$ file bcmserver
bcmserver: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, BuildID[sha1]=1bd7bfb49bc9c25fab7e00675c1ccc1e1f807487, for GNU/Linux 3.2.0, not stripped

How can i solve this issue?
I've checked other exec files that were compiled in the same way, all of them are 32-bit and all of them work fine with f.e. RAW sockets.

Just to make that clear - i use Raspbian directly to compile files (no cross-compilation).

@hartkopp
Copy link
Member

IIRC there was a discussion some time ago.

Can you try to add (or change)
arm_64bit=0

into /boot/config.txt

@JuraszekL
Copy link
Author

In my case the right file is under /boot/firmware/config.txt

This solution works fine!

candump can1
  can1  123   [8]  11 22 33 44 55 66 77 88
  can1  123   [8]  11 22 33 44 55 66 77 88
  can1  123   [8]  11 22 33 44 55 66 77 88
  can1  123   [8]  11 22 33 44 55 66 77 88
  can1  123   [8]  11 22 33 44 55 66 77 88

Can You please tell me what is wrong? I just want to understand the issue as a beginner.

Thank You.
Łukasz

@JuraszekL
Copy link
Author

How about downgrade my OS to Bullseye and use external toolchain like this one?

@hartkopp
Copy link
Member

Hi Łukasz,

the problem is, that the

struct bcm_msg_head {
	__u32 opcode;
	__u32 flags;
	__u32 count;
	struct bcm_timeval ival1, ival2;
	canid_t can_id;
	__u32 nframes;
	struct can_frame frames[];
};

has this

struct bcm_timeval {
	long tv_sec;
	long tv_usec;
};

where the long can be either 32 or 64 bit.
And this is the problem: You have a 32 bit user space running on a 64 bit kernel. And therefore the length check for the sizeof(struct bcm_mag_head) fails with errno 22 ("invalid argument").
That's the story.

IIRC Marc prepared a patch to solve this. I have to take a look at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants