The hook script fires, reads ppp0, and applies routes to whatever interface owns that name at that moment. Sometimes it is the tunnel you meant; sometimes it is a session that connected a minute earlier. The next reconnect moves the number, and the same script quietly configures the wrong link. The fix is to take the interface from the invocation that just ran, and to carry the intended profile alongside it.

Follow One Session From Options to Hook

Start where the session is created. xl2tpd launches pppd with the options file named by that tunnel's pppoptfile, so the plugin, the unit number and any profile marker are decided there rather than in a global file. A connection manager may generate its own options, which means editing /etc/ppp/options is not evidence that the tunnel you care about changed. When the link comes up, pppd runs the notification scripts from the distribution's dispatcher. Those scripts receive the interface name as the first argument, and the profile marker as the sixth.

The environment carries the same facts under names such as IFNAME and PPP_IPPARAM, but their availability depends on the dispatcher that is installed. Read the dispatcher before relying on a variable: some distributions keep the upstream argument order, others filter the environment before calling your script. A script that uses only $1 and the sixth argument works under both arrangements.

Read the Interface From the Invocation

The traditional hook receives the interface first. That positional value is the interface identifier that describes the session which triggered the script. Store it in a variable at the top, then use that variable for routes, firewall rules and teardown.

ipparam office-vpn

Attach a profile marker where the options are defined, not in the script. With that line in the tunnel's options file, every session created from that file carries office-vpn as its sixth argument. The script can branch on the marker while still acting on the real interface. Keep the two separate in the code, because the marker is stable and the interface is allocated per session.

Request a Name Only If Refusal Is Correct

A fixed name looks simpler than reading arguments, but it changes failure behaviour. The unit option requests a number for an outbound connection, and pppd falls back to a dynamic allocation when that unit is already busy. Nothing in that result reserves ppp0 for your profile.

ifname ppp-office

The ifname option behaves differently: if the requested name is already in use or cannot be assigned, pppd exits instead of choosing another. That is a policy choice, not a cosmetic rename. Use it when a second concurrent instance of the same profile should be refused, and confirm that the installed pppd and your connection manager pass the option through.

Either way, the name the script sees is the one to act on. A configured name does not remove the need to read the invocation, because a restarted session can still present a different name than the last one.

Make Teardown Match the Session You Configured

Routes and firewall rules outlive the script that created them, so teardown has to remove exactly the objects the session owns. Tag rules with the profile marker as well as the interface, and delete by that tag. If two tunnels can be up, deleting everything that mentions ppp is how one disconnect breaks the other connection.

Test the case that exposes the bug: bring up the second PPP session while the first is still connected, then reconnect the first and watch which interface the hook reports. A successful run with a single session proves nothing about name allocation. Repeat with the VPN stopped to confirm teardown leaves no stale route behind.

Keep the marker, the interface and the hook path in the deployment notes. When the number changes after a reboot, those three values explain why the script behaved differently without any configuration edit.

ХӀокхунах тера йаззамаш