Skip to content

Commit

Permalink
pppd/ipv6cp: Add ipv6-pre-up script.
Browse files Browse the repository at this point in the history
This is required because either ipcp or ipv6cp can come up first, or as
the only protocol, and once IPv6 parameters has been established, there
are actions that may need to be executed prior to bringing the interface
up.

Prior to this we can have an execution order like:

pppd[26615]: Script /etc/ppp/ipv6-up started (pid 28183)
pppd[26615]: Script /etc/ppp/ip-pre-up started (pid 28186)
pppd[26615]: Script /etc/ppp/ip-pre-up finished (pid 28186), status = 0x0
pppd[26615]: Script /etc/ppp/ip-up started (pid 28238)
pppd[26615]: Script /etc/ppp/ipv6-up finished (pid 28183), status = 0x0
pppd[26615]: Script /etc/ppp/ip-up finished (pid 28238), status = 0x0

ip ad sh shows that during ip-pre-up the interface state was already up:

ppp-ip-pre-up(ppp1)[28208]: 423: ppp1: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1480 qdisc pfifo_fast state UNKNOWN group default qlen 3
ppp-ip-pre-up(ppp1)[28208]:     link/ppp
ppp-ip-pre-up(ppp1)[28208]:     inet 10.1.0.0 peer 192.168.50.0/32 scope global ppp1
ppp-ip-pre-up(ppp1)[28208]:        valid_lft forever preferred_lft forever
ulsdns_monitor[28216]: 192.168.50.0 dev ppp1 proto kernel scope link src 10.1.0.0
ppp-ip-pre-up(ppp1)[28208]:     inet6 fe80::b4a3:c896:22bc:151f peer fe80::6/128 scope link
ppp-ip-pre-up(ppp1)[28208]:        valid_lft forever preferred_lft forever

In order to make this work properly, a system admin would need to take
the same action from ip-up and ipv6-up (probably in a locked manner) if
and only if the interface oper status is down.

As things stand one cannot depende on ip-up being executed whilst
interface is still in down state, and as such, the scription in the man
page is wrong too.

Signed-off-by: Jaco Kroon <[email protected]>
  • Loading branch information
jkroonza committed Jun 1, 2022
1 parent d7e62a8 commit 09e3d41
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 8 deletions.
24 changes: 16 additions & 8 deletions pppd/ipv6cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ struct protent ipv6cp_protent = {
};

static void ipv6cp_clear_addrs (int, eui64_t, eui64_t);
static void ipv6cp_script (char *);
static void ipv6cp_script (char *, int wait);
static void ipv6cp_script_done (void *);

/*
Expand Down Expand Up @@ -1236,6 +1236,8 @@ ipv6_demand_conf(int u)
eui64_magic_nz(wo->ourid);
}

ipv6cp_script(_PATH_IPV6PREUP, 1);

if (!sif6up(u))
return 0;
if (!sif6addr(u, wo->ourid, wo->hisid))
Expand Down Expand Up @@ -1343,6 +1345,9 @@ ipv6cp_up(fsm *f)
sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS);

} else {
/* run the pre-up script, if any, and wait for it to finish */
ipv6cp_script(_PATH_IPV6PREUP, 1);

/* bring the interface up for IPv6 */
if (!sif6up(f->unit)) {
if (debug)
Expand Down Expand Up @@ -1382,7 +1387,7 @@ ipv6cp_up(fsm *f)
*/
if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) {
ipv6cp_script_state = s_up;
ipv6cp_script(path_ipv6up);
ipv6cp_script(path_ipv6up, 0);
}
}

Expand Down Expand Up @@ -1433,7 +1438,7 @@ ipv6cp_down(fsm *f)
/* Execute the ipv6-down script */
if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) {
ipv6cp_script_state = s_down;
ipv6cp_script(path_ipv6down);
ipv6cp_script(path_ipv6down, 0);
}
}

Expand Down Expand Up @@ -1471,13 +1476,13 @@ ipv6cp_script_done(void *arg)
case s_up:
if (ipv6cp_fsm[0].state != OPENED) {
ipv6cp_script_state = s_down;
ipv6cp_script(path_ipv6down);
ipv6cp_script(path_ipv6down, 0);
}
break;
case s_down:
if (ipv6cp_fsm[0].state == OPENED) {
ipv6cp_script_state = s_up;
ipv6cp_script(path_ipv6up);
ipv6cp_script(path_ipv6up, 0);
}
break;
}
Expand All @@ -1489,7 +1494,7 @@ ipv6cp_script_done(void *arg)
* interface-name tty-name speed local-LL remote-LL.
*/
static void
ipv6cp_script(char *script)
ipv6cp_script(char *script, int wait)
{
char strspeed[32], strlocal[32], strremote[32];
char *argv[8];
Expand All @@ -1507,8 +1512,11 @@ ipv6cp_script(char *script)
argv[6] = ipparam;
argv[7] = NULL;

ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done,
NULL, 0);
if (wait)
run_program(script, argv, 0, NULL, NULL, 1);
else
ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done,
NULL, 0);
}

/*
Expand Down
1 change: 1 addition & 0 deletions pppd/pathnames.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#define _PATH_PSEUDONYM ".ppp_pseudonym"

#ifdef INET6
#define _PATH_IPV6PREUP _ROOT_PATH "/etc/ppp/ipv6-pre-up"
#define _PATH_IPV6UP _ROOT_PATH "/etc/ppp/ipv6-up"
#define _PATH_IPV6DOWN _ROOT_PATH "/etc/ppp/ipv6-down"
#endif
Expand Down
19 changes: 19 additions & 0 deletions pppd/pppd.8
Original file line number Diff line number Diff line change
Expand Up @@ -1839,6 +1839,11 @@ IP addresses assigned but is still down. This can be used to
add firewall rules before any IP traffic can pass through the
interface. Pppd will wait for this script to finish before bringing
the interface up, so this script should run quickly.

It has to be noted that if IPv6 is also in use, it's possible that IPv6CP will
complete prior to IPCP and will result in the interface already being UP when
this script is executed. Only one of ip\-pre\-up and ipv6\-pre\-up will be
executed with the interface still down.
.TP
.B /etc/ppp/ip\-up
A program or script which is executed when the link is available for
Expand All @@ -1856,6 +1861,20 @@ used for undoing the effects of the /etc/ppp/ip\-up and
invoked in the same manner and with the same parameters as the ip\-up
script.
.TP
.B /etc/ppp/ipv6\-pre\-up
A program or script which is executed just before the ppp network
interface is brought up for IPv6. It is executed with the same parameters as
the ip\-up script (below). At this point the interface exists and has
IP addresses assigned but is still down. This can be used to
add firewall rules before any IP traffic can pass through the
interface. Pppd will wait for this script to finish before bringing
the interface up, so this script should run quickly.

It has to be noted that if IPv4 is also in use, it's possible that IPCP will
complete prior to IPv6CP and will result in the interface already being UP when
this script is executed. Only one of ip\-pre\-up and ipv6\-pre\-up will be
executed with the interface still down.
.TP
.B /etc/ppp/ipv6\-up
Like /etc/ppp/ip\-up, except that it is executed when the link is available
for sending and receiving IPv6 packets. It is executed with the parameters
Expand Down

0 comments on commit 09e3d41

Please sign in to comment.