Skip to content

net: ppp: ipcp: Improvements to DNS option negotiation #93181

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

SeppoTakalo
Copy link
Contributor

When Kconfig option CONFIG_NET_L2_PPP_OPTION_DNS_USE is enabled, Zephyr should request two DNS addresses in IPCP negotiation by sending IPCP ConfReq for DNS otions using 0.0.0.0 as an address.

Remote peer may offer DNS by sending IPCP ConfNak with proper address. This is explained in RFC 1332 and RFC 1877 (DNS extension).

When no DNS is required, we should only send IPCP ConfReq for IP address, without having DNS fields in the same request.

However, when PPP is configured to serve a DNS using Kconfig option CONFIG_NET_L2_PPP_OPTION_SERVE_DNS it should serve the DNS address in the IPCP ConfNak message and from the ipcp.peer_options structure, not from the ipcp.my_options.

This might break backward compatibility outside this repository as DNS addresses used to be served from ipcp.my_options.

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR modifies PPP IPCP (Internet Protocol Control Protocol) negotiation to conditionally request DNS addresses based on configuration needs. The implementation ensures DNS options are only included in IPCP requests when actually required, and fixes DNS serving to use peer options instead of local options.

  • Conditionally compiles DNS-related functions and options based on CONFIG_NET_L2_PPP_OPTION_DNS_USE
  • Updates IPCP_NUM_MY_OPTIONS to reflect the actual number of options being used
  • Changes DNS serving logic to use peer_options instead of my_options for proper IPCP ConfNak responses

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
subsys/net/l2/ppp/ipcp.c Wraps DNS functions in conditional compilation and fixes DNS serving source
include/zephyr/net/ppp.h Makes IPCP_NUM_MY_OPTIONS conditional based on DNS usage configuration

@SeppoTakalo
Copy link
Contributor Author

Logs from running this against Linux PPPD

Without the change

Connect: ppp0 <--> /dev/gsmtty2
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0>]
rcvd [IPCP ConfReq id=0x1 <addr 10.234.139.142> <ms-dns1 62.241.198.245> <ms-dns2 62.241.198.246>]
sent [IPCP ConfRej id=0x1 <ms-dns1 62.241.198.245> <ms-dns2 62.241.198.246>]
rcvd [IPCP ConfNak id=0x1 <addr 10.234.139.142>]
sent [IPCP ConfReq id=0x2 <addr 10.234.139.142>]
rcvd [IPCP ConfReq id=0x2 <addr 10.234.139.142>]
sent [IPCP ConfAck id=0x2 <addr 10.234.139.142>]
rcvd [IPCP ConfAck id=0x2 <addr 10.234.139.142>]
local  IP address 10.234.139.142
remote IP address 10.234.139.142

As seen, Zephyr side is sending ms-dns options, even when it does not require a DNS address and Linux side is not requesting those. It needs to send extra ConfRef to tell Zephyr side that DNS options are ignored.

With this change

CONFIG_NET_L2_PPP_OPTION_SERVE_DNS=y
# CONFIG_NET_L2_PPP_OPTION_DNS_USE is unset

PPPD logs when using usepeerdns option so it requests a DNS address

Connect: ppp0 <--> /dev/gsmtty2
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [IPCP ConfReq id=0x1 <addr 10.179.183.207>]
sent [IPCP ConfAck id=0x1 <addr 10.179.183.207>]
rcvd [IPCP ConfNak id=0x1 <addr 10.179.183.207> <ms-dns1 62.241.198.245> <ms-dns2 62.241.198.246>]
sent [IPCP ConfReq id=0x2 <addr 10.179.183.207> <ms-dns1 62.241.198.245> <ms-dns2 62.241.198.246>]
rcvd [IPCP ConfAck id=0x2 <addr 10.179.183.207> <ms-dns1 62.241.198.245> <ms-dns2 62.241.198.246>]
local  IP address 10.179.183.207
remote IP address 10.179.183.207
primary   DNS address 62.241.198.245
secondary DNS address 62.241.198.246

PPPD logs without the usepeerdns option

Connect: ppp0 <--> /dev/gsmtty2
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0>]
rcvd [IPCP ConfReq id=0x2 <addr 10.234.136.153>]
sent [IPCP ConfAck id=0x2 <addr 10.234.136.153>]
rcvd [IPCP ConfNak id=0x1 <addr 10.234.136.153>]
sent [IPCP ConfReq id=0x2 <addr 10.234.136.153>]
rcvd [IPCP ConfAck id=0x2 <addr 10.234.136.153>]
local  IP address 10.234.136.153
remote IP address 10.234.136.153

As seen, when PPPD is not requesting a ms-dns option, it is not send anymore.

@SeppoTakalo SeppoTakalo force-pushed the ppp_dns_offer_upstream branch from a7045b2 to b47e462 Compare July 16, 2025 08:42
When Kconfig option CONFIG_NET_L2_PPP_OPTION_DNS_USE is enabled,
Zephyr should request two DNS addresses in IPCP negotiation by sending
IPCP ConfReq for DNS otions using 0.0.0.0 as an address.

Remote peer may offer DNS by sending IPCP ConfNak with proper address.
This is explained in RFC 1332 and RFC 1877 (DNS extension).

When no DNS is required, we should only send IPCP ConfReq for IP
address, without having DNS fields in the same request.

However, when PPP is configured to serve a DNS using Kconfig option
CONFIG_NET_L2_PPP_OPTION_SERVE_DNS it should serve the DNS address in the
IPCP ConfNak message and from the ipcp.peer_options structure, not from
the ipcp.my_options.

This might break backward compatibility outside this repository
as DNS addresses used to be served from ipcp.my_options.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
@SeppoTakalo SeppoTakalo force-pushed the ppp_dns_offer_upstream branch from b47e462 to 774e2dc Compare July 16, 2025 09:28
rlubos
rlubos previously approved these changes Jul 16, 2025
There are cases, for example when peer is requesting two DNS
addresses, but we can only give one, we should reject the secondary
DNS request first, before sending NAK to acceptable options.

Option parser can reject a parameter by returning -ENOTSUP and when
it wants to NAK the parameter, it returns -EINVAL.

On RFC 1661:
Configure-Reject
  If some Configuration Options received in a Configure-Request are
  not recognizable or are not acceptable for negotiation (as
  configured by a network administrator), then the implementation
  MUST transmit a Configure-Reject.

Configure-Nak
  If every instance of the received Configuration Options is
  recognizable, but some values are not acceptable, then the
  implementation MUST transmit a Configure-Nak.

So as stated by RFC, we should start the negotiation by rejecting all
parameters that we cannot configure. I added an example of rejecting
DNS requests, if we don't have those.

Signed-off-by: Seppo Takalo <seppo.takalo@nordicsemi.no>
Copy link

@SeppoTakalo
Copy link
Contributor Author

After testing this a bit against the Linux PPPD, I decided to add a second commit into this PR.

net: ppp: Allow peer-options to be rejected

There are cases, for example when peer is requesting two DNS
addresses, but we can only give one, we should reject the secondary
DNS request first, before sending NAK to acceptable options.

Option parser can reject a parameter by returning -ENOTSUP and when
it wants to NAK the parameter, it returns -EINVAL.

On RFC 1661:
Configure-Reject

If some Configuration Options received in a Configure-Request are
not recognizable or are not acceptable for negotiation (as
configured by a network administrator), then the implementation
MUST transmit a Configure-Reject.

Configure-Nak

If every instance of the received Configuration Options is
recognizable, but some values are not acceptable, then the
implementation MUST transmit a Configure-Nak.

So as stated by RFC, we should start the negotiation by rejecting all
parameters that we cannot configure. I added an example of rejecting
DNS requests, if we don't have those.

Test log from Linux PPPD

Connect: ppp0 <--> /dev/gsmtty2
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [IPCP ConfReq id=0x1 <addr 10.202.237.216>]
sent [IPCP ConfAck id=0x1 <addr 10.202.237.216>]
rcvd [IPCP ConfRej id=0x1 <ms-dns2 0.0.0.0>]
sent [IPCP ConfReq id=0x2 <addr 0.0.0.0> <ms-dns1 0.0.0.0>]
rcvd [IPCP ConfNak id=0x2 <addr 10.202.237.216> <ms-dns1 8.8.8.8>]
sent [IPCP ConfReq id=0x3 <addr 10.202.237.216> <ms-dns1 8.8.8.8>]
rcvd [IPCP ConfAck id=0x3 <addr 10.202.237.216> <ms-dns1 8.8.8.8>]
local  IP address 10.202.237.216
remote IP address 10.202.237.216
primary   DNS address 8.8.8.8

As seen, now it clearly rejects the ms-dns2 parameter first, as I had only one DNS configured.
Previously it offered 0.0.0.0 as a secondary and then NAKed that on next request, ended up in NAK loop, that timed out after CONFIG_NET_L2_PPP_MAX_NACK_LOOPS by rejecting the request.

@SeppoTakalo SeppoTakalo requested a review from rlubos July 16, 2025 13:46
@SeppoTakalo SeppoTakalo changed the title net: ppp: ipcp: Don't request DNS if not needed net: ppp: ipcp: Improvements to DNS option negotiation Jul 16, 2025
@zephyrbot zephyrbot requested review from pdgendt and ssharks July 17, 2025 02:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants