ppp-project / ppp

Paul's PPP Package: PPP daemon and associated utilities | Official GitHub repo: https://github.com/ppp-project/ppp
https://github.com/ppp-project/ppp
Other
384 stars 228 forks source link

API to find the underlying interface for PPPoE. #398

Open isomer opened 1 year ago

isomer commented 1 year ago

I'd like to have precise timing for packets sent over a PPPoE link. I can do this manually by turning on hardware timestamping for the underlying ethernet interface and everything works fine. The problem is that I can't programatically given an interface (such as ppp0) discover what the underlying ethernet interface is so I can automatically enable hardware timestamping. My current solution is just enable it on all interface, but this has various downsides.

With netlink I can discover the fd that corresponds to the ppp interface, but I can't easily discover which process that fd is in, and it is fairly rude to start calling ioctl's on another processes fd. Ideally, netlink would provide some indication about the underlying channel.

This functionality would be generally useful for systems such as ntp.

Neustradamus commented 1 year ago

@enaess: ^

enaess commented 1 year ago

@isomer Are you able to provide us with some more details on your feature request? How do you intend for your system to work, and how are you getting the interface name now? Are you asking if there is a function that would be able to get the name of the pppoe device from a plugin?

pali commented 1 year ago

This feature is something which can be useful also for "ip link" output. So user would know to which eth interface is ppp interface bound. In the same way how user can read from "ip link" output to which DSA or mater bridge interface is which interface connected. Also it would make sense to be able to read which PPPoE tag is using particular ppp interface. Or to which PPPoE concentrator it is connected (eth MAC address). All these information are just "setup data" of the interface which are needed for any debugging and getting them at runtime is the best option how to check that everything is correctly configured / connected.

I think that the proper way is to implement NLM_F_DUMP API in kernel for ppp interface. Similarly NLM_F_ECHO API is needed to avoid any race conditions during creation of ppp interfaces by pppd daemon. See my older discussion about this issue: https://lore.kernel.org/netdev/20210802172346.yj3ia7czg6o7kgn7@pali/

pali commented 1 year ago

@isomer wrote:

With netlink I can discover the fd that corresponds to the ppp interface

It is really already possible? Could you provide some example how to do it? Because I though that it is currently impossible.

and it is fairly rude to start calling ioctl's on another processes fd.

Yes, it is a really bad idea to do it. But should be safe to call some fstat() and then if it is socket, call some ioctl/syscall for getting information about socket, which does not change state of the socket.

Ultimately we need to retrieve struct sockaddr_pppox for that PPPoE interface, but I think this is not currently possible even if you have socket file descriptor. This is something which should be included in NLM_F_DUMP API once it is implemented.

Neustradamus commented 4 weeks ago

@isomer: Have you seen @pali comments?

isomer commented 4 weeks ago

@isomer Are you able to provide us with some more details on your feature request? How do you intend for your system to work, and how are you getting the interface name now? Are you asking if there is a function that would be able to get the name of the pppoe device from a plugin?

When I bind to an interface, I want to enable hardware timestampping for that interface. However, if this interface is a pppoe interface, I obviously can't enable hardware timestamppng as ppp doesn't have hardware. If I turn on hardware timestamping on the underlying ethernet interface (assuming it supports it) then the packets are correctly timestamped, however there's no way for me to discover what the underlying interface is without asking the administrator. I'd like to automate this process, but I don't currently have a way.

The only netlink message I can find tells me the file descriptor, which is not particularly useful. Presumably I could try and find the pppd process, and open /proc/<pid>/fd/<fd> which seems like a particularly terrible plan.

paulusmack commented 3 weeks ago

This is part of the reason I added the tdb database stuff; i.e. it would be possible to have a separate program that queries the tdb database to get a list of ppp connections along with what interface etc. each one is using. However, tdb only gets configured in when multilink is enabled (tdb is only really required for multilink). I have been considering changing from tdb to sqlite. That should make it easier to write programs to query the database and dig out the sort of information you are looking for.