Skip to content

Commit

Permalink
pppd: consolidate the interface up/down code a bit.
Browse files Browse the repository at this point in the history
This no longer differentiates between which sub protocols brings an
interface up or down, merely tracks which sub protocols have brought up
and interface, and which have not yet taken it down.

There is one caveat here, I use pointer comparison on these names, so
the absolutely cannot be anything other than a compile-time constant,
and I'm not sure whether or not at least -O1 is required or not, ie, if
the compiler will eliminate multiple "STRINGS" to a single instance in
memory.

I'm unable to test the solaris code, but I don't see any reason why this
should not work.

Signed-off-by: Jaco Kroon <[email protected]>
  • Loading branch information
jkroonza committed Aug 24, 2022
1 parent 87640b7 commit bf9329e
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 204 deletions.
6 changes: 3 additions & 3 deletions pppd/ipcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,7 @@ ip_demand_conf(int u)
if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
return 0;
ipcp_script(PPP_PATH_IPPREUP, 1);
if (!sifup(u))
if (!set_ifup("IPCP"))
return 0;
if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
return 0;
Expand Down Expand Up @@ -1943,7 +1943,7 @@ ipcp_up(fsm *f)
}

/* bring the interface up for IP */
if (!sifup(f->unit)) {
if (!set_ifup("IPCP")) {
if (debug)
warn("Interface failed to come up");
ipcp_close(f->unit, "Interface configuration failed");
Expand Down Expand Up @@ -2038,7 +2038,7 @@ ipcp_down(fsm *f)
sifnpmode(f->unit, PPP_IP, NPMODE_QUEUE);
} else {
sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
sifdown(f->unit);
set_ifdown("IPCP");
ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
ipcp_hisoptions[f->unit].hisaddr, 0);
}
Expand Down
21 changes: 5 additions & 16 deletions pppd/ipv6cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1237,14 +1237,10 @@ ipv6_demand_conf(int u)
eui64_magic_nz(wo->ourid);
}

if (!sif6up(u))
if (!set_ifup("IPV6CP"))
return 0;
if (!sif6addr(u, wo->ourid, wo->hisid))
return 0;
#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
if (!sifup(u))
return 0;
#endif
if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE))
return 0;
if (wo->default_route)
Expand Down Expand Up @@ -1345,9 +1341,9 @@ ipv6cp_up(fsm *f)

} else {
/* bring the interface up for IPv6 */
if (!sif6up(f->unit)) {
if (!set_ifup("IPV6CP")) {
if (debug)
warn("sif6up failed (IPV6)");
warn("set_ifup failed (IPV6)");
ipv6cp_close(f->unit, "Interface configuration failed");
return;
}
Expand Down Expand Up @@ -1418,17 +1414,10 @@ ipv6cp_down(fsm *f)
sifnpmode(f->unit, PPP_IPV6, NPMODE_QUEUE);
} else {
sifnpmode(f->unit, PPP_IPV6, NPMODE_DROP);
#if !defined(__linux__) && !(defined(SVR4) && (defined(SNI) || defined(__USLC)))
sif6down(f->unit);
#endif
ipv6cp_clear_addrs(f->unit,
ipv6cp_clear_addrs(f->unit,
ipv6cp_gotoptions[f->unit].ourid,
ipv6cp_hisoptions[f->unit].hisid);
#if defined(__linux__)
sif6down(f->unit);
#elif defined(SVR4) && (defined(SNI) || defined(__USLC))
sifdown(f->unit);
#endif
set_ifdown("IPV6CP");
}

/* Execute the ipv6-down script */
Expand Down
85 changes: 85 additions & 0 deletions pppd/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ char *progname; /* Name of this program */
char hostname[MAXNAMELEN]; /* Our hostname */
static char pidfilename[MAXPATHLEN]; /* name of pid file */
static char linkpidfile[MAXPATHLEN]; /* name of linkname pid file */
static const char** up_protos = NULL; /* simple list of names of sub protocols which has signalled the interface into an UP state, or NULL if the interface is down */
char ppp_devnam[MAXPATHLEN]; /* name of PPP tty (maybe ttypx) */
uid_t uid; /* Our real user-id */
struct notifier *pidchange = NULL;
Expand Down Expand Up @@ -747,6 +748,83 @@ set_ifunit(int iskey)
}
}

/*
* set_ifup - called in order to set the ppp interface to up, if not already
* brought up.
*
* It's important that the sub-protocol not be a dynamically allocated string, ie,
* use set_ipup("IPCP") ...
*/
int
set_ifup(const char* name)
{
int i;
const char** t;

if (!up_protos && !netif_set_up())
return 0;

i = 0;
while (up_protos && up_protos[i]) {
if (up_protos[i] == name) {
warn("%s previously signalled ifup, this is probably a bug in the protocol.",
name);
return 1;
}
++i;
}
info("%s is now UP", name);

/* i is index where we insert the sub protocol */
t = realloc(up_protos, (i + 2) * sizeof(*up_protos));
if (t == NULL) {
error("Memory allocation error trying to add %s to the list of UP protocols.", name);
} else {
up_protos = t;
up_protos[i] = name;
up_protos[i+1] = NULL;
}

return 1;
}

/*
* set_ifdown - called in order to set the ppp interface to down, the interface will
* only be downned if all sub protocols have signalled down.
*
* It's important that the sub-protocol not be a dynamically allocated string, ie,
* use set_ipup("IPCP") ...
*/
int
set_ifdown(const char* name)
{
int i = 0;
const char** t;

while (up_protos && up_protos[i] && up_protos[i] != name)
++i;

if (!up_protos || !up_protos[i]) {
error("%s has not signalled ifup, or has already signalled ifdown.");
return 0;
}

while (up_protos[i]) {
up_protos[i] = up_protos[i+1];
++i;
}

info("%s is now DOWN", name);

if (*up_protos)
return 1;

free(up_protos);
up_protos = NULL;

return netif_set_down();
}

/*
* detach - detach us from the controlling terminal.
*/
Expand Down Expand Up @@ -1174,6 +1252,13 @@ die(int status)
static void
cleanup(void)
{
if (up_protos) {
const char** remprotos = up_protos;
warn("Some protocols were left UP at time of cleanup.");
while (*remprotos)
set_ifdown(*remprotos++);
free(up_protos);
}
sys_cleanup();

if (fd_ppp >= 0)
Expand Down
8 changes: 4 additions & 4 deletions pppd/pppd.h
Original file line number Diff line number Diff line change
Expand Up @@ -702,21 +702,21 @@ int get_idle_time(int, struct ppp_idle *);
/* Find out how long link has been idle */
int get_ppp_stats(int, struct pppd_stats *);
/* Return link statistics */
int set_ifup(const char*); /* Set the PPP interface to UP for a named sub protocol */
int set_ifdown(const char*); /* Set the PPP interface to DOWN for a named sub protocol */
void netif_set_mtu(int, int); /* Set PPP interface MTU */
int netif_get_mtu(int); /* Get PPP interface MTU */
int netif_set_up(); /* Configure i/f up (system specific) */
int netif_set_down(); /* Configure i/f down (system specific) */
int sifvjcomp(int, int, int, int);
/* Configure VJ TCP header compression */
int sifup(int); /* Configure i/f up for one protocol */
int sifnpmode(int u, int proto, enum NPmode mode);
/* Set mode for handling packets for proto */
int sifdown(int); /* Configure i/f down for one protocol */
int sifaddr(int, u_int32_t, u_int32_t, u_int32_t);
/* Configure IPv4 addresses for i/f */
int cifaddr(int, u_int32_t, u_int32_t);
/* Reset i/f IP addresses */
#ifdef PPP_WITH_IPV6CP
int sif6up(int); /* Configure i/f up for IPv6 */
int sif6down(int); /* Configure i/f down for IPv6 */
int sif6addr(int, eui64_t, eui64_t);
/* Configure IPv6 addresses for i/f */
int cif6addr(int, eui64_t, eui64_t);
Expand Down
101 changes: 18 additions & 83 deletions pppd/sys-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,6 @@ int new_style_driver = 0;
static char loop_name[20];
static unsigned char inbuf[512]; /* buffer for chars read from loopback */

static int if_is_up; /* Interface has been marked up */
static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */
static int have_default_route; /* Gateway for default route added */
static int have_default_route6; /* Gateway for default IPv6 route added */
static struct rtentry old_def_rt; /* Old default route */
Expand Down Expand Up @@ -283,7 +281,7 @@ static void decode_version (char *buf, int *version, int *mod, int *patch);
static int set_kdebugflag(int level);
static int ppp_registered(void);
static int make_ppp_unit(void);
static int setifstate (int u, int state);
static int setifstate(int state);

extern u_char inpacket_buf[]; /* borrowed from main.c */

Expand Down Expand Up @@ -519,18 +517,6 @@ void sys_init(void)

void sys_cleanup(void)
{
/*
* Take down the device
*/
if (if_is_up) {
if_is_up = 0;
sifdown(0);
}
#ifdef PPP_WITH_IPV6CP
if (if6_is_up)
sif6down(0);
#endif

/*
* Delete any routes through the device.
*/
Expand Down Expand Up @@ -3083,79 +3069,12 @@ int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
return 1;
}

/********************************************************************
*
* sifup - Config the interface up and enable IP packets to pass.
*/

int sifup(int u)
{
int ret;

if ((ret = setifstate(u, 1)))
if_is_up++;

return ret;
}

/********************************************************************
*
* sifdown - Disable the indicated protocol and config the interface
* down if there are no remaining protocols.
*/

int sifdown (int u)
{
if (if_is_up && --if_is_up > 0)
return 1;

#ifdef PPP_WITH_IPV6CP
if (if6_is_up)
return 1;
#endif /* PPP_WITH_IPV6CP */

return setifstate(u, 0);
}

#ifdef PPP_WITH_IPV6CP
/********************************************************************
*
* sif6up - Config the interface up for IPv6
*/

int sif6up(int u)
{
int ret;

if ((ret = setifstate(u, 1)))
if6_is_up = 1;

return ret;
}

/********************************************************************
*
* sif6down - Disable the IPv6CP protocol and config the interface
* down if there are no remaining protocols.
*/

int sif6down (int u)
{
if6_is_up = 0;

if (if_is_up)
return 1;

return setifstate(u, 0);
}
#endif /* PPP_WITH_IPV6CP */

/********************************************************************
*
* setifstate - Config the interface up or down
*/

static int setifstate (int u, int state)
static int setifstate (int state)
{
struct ifreq ifr;

Expand All @@ -3180,6 +3099,22 @@ static int setifstate (int u, int state)
return 1;
}

/********************************************************************
* netif_set_up - Config the interface up
*/
int netif_set_up()
{
return setifstate(1);
}

/********************************************************************
* netif_set_down - Config the interface down
*/
int netif_set_down()
{
return setifstate(0);
}

/********************************************************************
*
* sifaddr - Config the interface IP addresses and netmask.
Expand Down
Loading

0 comments on commit bf9329e

Please sign in to comment.