Skip to content

Implement support for LLC sockets#1948

Open
ernestask wants to merge 1 commit intoobgm:developfrom
ernestask:llc
Open

Implement support for LLC sockets#1948
ernestask wants to merge 1 commit intoobgm:developfrom
ernestask:llc

Conversation

@ernestask
Copy link
Copy Markdown
Contributor

Useful in embedded contexts, where devices might only have a link-layer connection, but still need to exchange information.

@ernestask
Copy link
Copy Markdown
Contributor Author

The bulk of the code is for address/port/URI handling.

Since this is something that is used at $JOB, I’d love to get this (seemingly) generic feature merged (of course, in a form that is deemed appropriate) and only keep hacking $JOB-specific things on top.

@ernestask ernestask force-pushed the llc branch 5 times, most recently from a06fffd to a69852a Compare April 9, 2026 12:00
@ernestask
Copy link
Copy Markdown
Contributor Author

Ping, is this something that could live upstream?

@mrdeep1
Copy link
Copy Markdown
Collaborator

mrdeep1 commented Apr 13, 2026

It is something that can be added in upstream , modelled as how AF_UNIX support is done. However, how you specify the Host in the URI in a way that the parser can understand and differentiate between IPv4, IPv6, AF_UNIX and AF_LLC is what I am thinking about.

I am thinking something like

coap://llc[00:11:22:33:44:55]:sap/some/path

where :sap is mandatory. then for the -a option (client) or -A option (server) this could be provided as llc[00:11:22:33:44:55]:sap or perhaps coaps://llc[00:11:22:33:44:55]:sap to differentiate between different upper layer protocols.

I also would prefer not to have to use the -4 option, but use the equivalent AF_UNIX support so that should another AF_* be added, it is easy to slot in.

Support would need to be added in for DTLS and potentially TCP(Stream) and TLS.

@ernestask
Copy link
Copy Markdown
Contributor Author

Thanks for taking a look!

It is something that can be added in upstream , modelled as how AF_UNIX support is done. However, how you specify the Host in the URI in a way that the parser can understand and differentiate between IPv4, IPv6, AF_UNIX and AF_LLC is what I am thinking about.

I am thinking something like

coap://llc[00:11:22:33:44:55]:sap/some/path

where :sap is mandatory. then for the -a option (client) or -A option (server) this could be provided as llc[00:11:22:33:44:55]:sap or perhaps coaps://llc[00:11:22:33:44:55]:sap to differentiate between different upper layer protocols.

I also would prefer not to have to use the -4 option, but use the equivalent AF_UNIX support so that should another AF_* be added, it is easy to slot in.

Your suggestion looks pretty clean, I like it. Trying to figure out URIs for this was the most time-consuming. :)

Support would need to be added in for DTLS and potentially TCP(Stream) and TLS.

Aye.

Switching back to draft, will change the address handling and then look at additional protocol support.

@ernestask ernestask marked this pull request as draft April 13, 2026 14:01
@ernestask ernestask force-pushed the llc branch 4 times, most recently from 867dcfa to f44f6d2 Compare April 15, 2026 07:58
@ernestask
Copy link
Copy Markdown
Contributor Author

DTLS and TCP works, didn’t test TLS, but nothing should prevent that from working as well.

One caveat: getpeername() fails for SOCK_STREAM sockets:

Apr 15 10:58:36.862  1 WARN coap_socket_connect_tcp1: getpeername: Transport endpoint is not connected

I believe that one is a kernel bug, so I proposed a fix: https://lore.kernel.org/netdev/20260415063457.1008868-1-ernestas.k@iconn-networks.com/T/

Example use (of course, substitute own interface addresses):

  • Server
coap-server -U coap+tcp -A 'llc[00:03:7f:12:79:79]:dc'
  • Client
coap-client -a 'llc[2a:dc:4b:14:4c:41]:dc' 'coap+tcp://llc[00:03:7f:12:79:79]:dc/time'

@ernestask ernestask marked this pull request as ready for review April 15, 2026 08:14
@mrdeep1
Copy link
Copy Markdown
Collaborator

mrdeep1 commented Apr 16, 2026

Thanks for doing this.

coap_print_addr() and coap_print_ip_addr() need updating to handle AF_LLC.

Server man pages (and usage()) need updating for -U option usage, and man / usage() need updating with a LLC example.

One caveat: getpeername() fails for SOCK_STREAM sockets:

Need to do a LLC check here I guess.

@mrdeep1
Copy link
Copy Markdown
Collaborator

mrdeep1 commented Apr 16, 2026

Also wondering whether :sap should be in hex, or decimal to be compatible with other host:port definitions.

@ernestask
Copy link
Copy Markdown
Contributor Author

Also wondering whether :sap should be in hex, or decimal to be compatible with other host:port definitions.

IMO, it would be somewhat unusual to use decimal numbers in this case.

@ernestask ernestask force-pushed the llc branch 2 times, most recently from 725721f to ca1a8dc Compare April 16, 2026 17:21
@ernestask
Copy link
Copy Markdown
Contributor Author

coap_print_addr() and coap_print_ip_addr() need updating to handle AF_LLC.

Done, pending decision re hex vs decimal notation.

Server man pages (and usage()) need updating for -U option usage, and man / usage() need updating with a LLC example.

Updated man pages and added address examples for server under -A in usage, not sure what would be a better place there.

One caveat: getpeername() fails for SOCK_STREAM sockets:

Need to do a LLC check here I guess.

Done, hopefully I’m not wrong about the kernel issue and that will resolve itself eventually.

Copy link
Copy Markdown
Collaborator

@mrdeep1 mrdeep1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general looking good.

In your environment what is the SAP you are using?

Comment thread examples/coap-server.c Outdated
Comment thread examples/coap-server.c Outdated
Comment thread include/coap3/coap_address.h Outdated
Comment thread man/coap-server.txt.in Outdated
Comment thread man/coap_address.txt.in Outdated
Comment thread man/coap_address.txt.in Outdated
Comment thread src/coap_address.c Outdated
#define COAP_SOCKET_CAN_CONNECT 0x0800 /**< non blocking client socket can now connect without blocking */
#define COAP_SOCKET_MULTICAST 0x1000 /**< socket is used for multicast communication */
#define COAP_SOCKET_SLAVE 0x2000 /**< socket is a slave socket - do not close */
#define COAP_SOCKET_WANT_SENDTO 0x4000 /**< socket requires a destination address for sending */
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not believe that COAP_SOCKET_WANT_SENDTO is needed as COAP_SOCKET_CONNECTED is set when COAP_SOCKET_WANT_SENDTO is set.

Copy link
Copy Markdown
Contributor Author

@ernestask ernestask Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps the flag itself isn’t necessary, but sendmsg() without a destination address results in the local socket address being used:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/net/llc/af_llc.c?id=85cb0757d7e1f9370a8b52a8b8144c37941cba0a#n945

Notice how &llc->addr is used and not &llc->daddr:

if (addr) {
	if (msg->msg_namelen < sizeof(*addr))
		goto out;
} else {
	if (llc_ui_addr_null(&llc->addr))
		goto out;
	addr = &llc->addr;
}

Not sure if this behavior is intended, need to spend more time looking at the code, but some way to force using sendto() is needed. Otherwise, the client will just send messages to itself (Wireshark quickly revealed why nothing seemed to work).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we need to keep this. However, it is required to not do a send(), but to do a sendmsg() or sendto() depending on whether HAVE_STRUCT_CMSGHDR is set or not circa line 680 in src/coap_dgrm_posix.c.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, sorry, I use those three interchangably (since send() and sendto() are pretty much just wrappers for sendmsg(), at least on Linux). Indeed the goal is to avoid plain send() and go straight to sendmsg() with constructed header or sendto() with destination address.

Should I change anything here?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change required here.

@ernestask
Copy link
Copy Markdown
Contributor Author

In general looking good.

In your environment what is the SAP you are using?

I see equal parts of AC and AE. This is all before my time, so I can just guess that random not-well-known values were picked.

@mrdeep1
Copy link
Copy Markdown
Collaborator

mrdeep1 commented Apr 17, 2026

We need to document a client example in man/coap-client.txt.in for llc. It seems we need the -a option for coap/coaps, but not for coap+tcp/coaps+tcp..

@ernestask
Copy link
Copy Markdown
Contributor Author

ernestask commented Apr 17, 2026

We need to document a client example in man/coap-client.txt.in for llc. It seems we need the -a option for coap/coaps, but not for coap+tcp/coaps+tcp..

Ah, that would be something to fix. AF_LLC sockets auto-bind to the first available interface if not bound explicitly. Requiring -a always rules out surprising behavior.

Useful in embedded contexts, where devices might only have a link-layer
connection, but still need to exchange information.
@ernestask
Copy link
Copy Markdown
Contributor Author

Pushed a change to require -a for clients when the destination is an LLC host and added an example to the client man page.

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

Successfully merging this pull request may close these issues.

2 participants