Skip to content

Commit

Permalink
Rework default route handling.
Browse files Browse the repository at this point in the history
1.  replacedefaultroute option is no longer functional.
2.  default route will now always be appended at defaultroute-metric (both
    IPv4 and IPv6) if defaultroute{.6} is given.

Closes: #473
Signed-off-by: Jaco Kroon <[email protected]>
  • Loading branch information
jkroonza committed Feb 11, 2025
1 parent 9f612dc commit 99151ea
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 309 deletions.
76 changes: 40 additions & 36 deletions pppd/ipcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ u_int32_t netmask = 0; /* IP netmask to set on interface */
bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */
bool noremoteip = 0; /* Let him have no IP address */

unsigned dfl_route_metric = 0; /* metric of the default route to set over the PPP link */

ip_up_hook_fn *ip_up_hook = NULL;
ip_down_hook_fn *ip_down_hook = NULL;
ip_choose_hook_fn *ip_choose_hook = NULL;
Expand Down Expand Up @@ -136,6 +138,8 @@ static int setvjslots (char **);
static int setdnsaddr (char **);
static int setwinsaddr (char **);
static int setnetmask (char **);
static int replacedefaultroute_nonfunctional();

int setipaddr (char *, char **, int);
static void printipaddr (struct option *, void (*)(void *, char *,...),void *);

Expand Down Expand Up @@ -196,15 +200,20 @@ static struct option ipcp_option_list[] = {
"disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
&ipcp_wantoptions[0].default_route },

{ "defaultroute-metric", o_int, &dfl_route_metric,
"Metric to use for the default route (Linux only; default 0)",
OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 },

#ifdef __linux__
{ "replacedefaultroute", o_bool,
&ipcp_wantoptions[0].replace_default_route,
"Replace default route", OPT_PRIV | 1
},
{ "noreplacedefaultroute", o_bool,
&ipcp_wantoptions[0].replace_default_route,
"Do not replace default route", 0 },
{ "replacedefaultroute", o_special_noarg,
&replacedefaultroute_nonfunctional,
"Removed option to replace default route", OPT_PRIV
},
{ "noreplacedefaultroute", o_special_noarg,
&replacedefaultroute_nonfunctional,
"Removed option to not replace default route", 0 },
#endif

{ "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
"Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
{ "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
Expand Down Expand Up @@ -284,7 +293,7 @@ struct protent ipcp_protent = {
ip_active_pkt
};

static void ipcp_clear_addrs (int, u_int32_t, u_int32_t, bool);
static void ipcp_clear_addrs (int, u_int32_t, u_int32_t);
static void ipcp_script (char *, int); /* Run an up/down script */
static void ipcp_script_done (void *);

Expand Down Expand Up @@ -437,7 +446,7 @@ setipaddr(char *arg, char **argv, int doit)
return 0;
if (!doit)
return 1;

/*
* If colon first character, then no local addr.
*/
Expand All @@ -459,7 +468,7 @@ setipaddr(char *arg, char **argv, int doit)
*colon = ':';
prio_local = option_priority;
}

/*
* If colon last character, then no remote addr.
*/
Expand Down Expand Up @@ -527,6 +536,13 @@ setnetmask(char **argv)
return (1);
}

static int
replacedefaultroute_nonfunctional()
{
ppp_option_error("replacedefaultroute and noreplacedefaultroute route options no longer has any efffect. Please refer to the man page for defaultroute and defaultroute-metric.");
return 1;
}

int
parse_dotted_ip(char *p, u_int32_t *vp)
{
Expand Down Expand Up @@ -851,7 +867,7 @@ ipcp_addci(fsm *f, u_char *ucp, int *lenp)
ADDCIWINS(CI_MS_WINS1, go->req_wins1, go->winsaddr[0]);

ADDCIWINS(CI_MS_WINS2, go->req_wins2, go->winsaddr[1]);

*lenp -= len;
}

Expand Down Expand Up @@ -1456,7 +1472,7 @@ ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
* Reset all his options.
*/
BZERO(ho, sizeof(*ho));

/*
* Process all his options.
*/
Expand Down Expand Up @@ -1566,7 +1582,7 @@ ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */
break;
}

ho->neg_addr = 1;
ho->hisaddr = ciaddr1;
break;
Expand Down Expand Up @@ -1610,7 +1626,7 @@ ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
orc = CONFNAK;
}
break;

case CI_COMPRESSTYPE:
if (!ao->neg_vj ||
(cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) {
Expand All @@ -1629,7 +1645,7 @@ ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
ho->vj_protocol = cishort;
if (cilen == CILEN_VJ) {
GETCHAR(maxslotindex, p);
if (maxslotindex > ao->maxslotindex) {
if (maxslotindex > ao->maxslotindex) {
orc = CONFNAK;
if (!reject_if_disagree){
DECPTR(1, p);
Expand Down Expand Up @@ -1776,8 +1792,7 @@ ip_demand_conf(int u)
if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
return 0;
if (wo->default_route)
if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
wo->replace_default_route))
if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
default_route_set[u] = 1;
if (wo->proxy_arp)
if (sifproxyarp(u, wo->hisaddr))
Expand Down Expand Up @@ -1878,8 +1893,7 @@ ipcp_up(fsm *f)
*/
if (demand) {
if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
wo->replace_default_route);
ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
if (go->ouraddr != wo->ouraddr) {
warn("Local IP address changed to %I", go->ouraddr);
ppp_script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
Expand All @@ -1904,9 +1918,8 @@ ipcp_up(fsm *f)
}

/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
wo->replace_default_route))
if (ipcp_wantoptions[f->unit].default_route)
if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
default_route_set[f->unit] = 1;

/* Make a proxy ARP entry if requested. */
Expand Down Expand Up @@ -1964,9 +1977,8 @@ ipcp_up(fsm *f)
sifnpmode(f->unit, PPP_IP, NPMODE_PASS);

/* assign a default route through the interface if required */
if (ipcp_wantoptions[f->unit].default_route)
if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
wo->replace_default_route))
if (ipcp_wantoptions[f->unit].default_route)
if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
default_route_set[f->unit] = 1;

/* Make a proxy ARP entry if requested. */
Expand Down Expand Up @@ -2043,7 +2055,7 @@ ipcp_down(fsm *f)
sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
sifdown(f->unit);
ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
ipcp_hisoptions[f->unit].hisaddr, 0);
ipcp_hisoptions[f->unit].hisaddr);
}

/* Execute the ip-down script */
Expand All @@ -2059,21 +2071,13 @@ ipcp_down(fsm *f)
* proxy arp entries, etc.
*/
static void
ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute)
ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr)
{
if (proxy_arp_set[unit]) {
cifproxyarp(unit, hisaddr);
proxy_arp_set[unit] = 0;
}
/* If replacedefaultroute, sifdefaultroute will be called soon
* with replacedefaultroute set and that will overwrite the current
* default route. This is the case only when doing demand, otherwise
* during demand, this cifdefaultroute would restore the old default
* route which is not what we want in this case. In the non-demand
* case, we'll delete the default route and restore the old if there
* is one saved by an sifdefaultroute with replacedefaultroute.
*/
if (!replacedefaultroute && default_route_set[unit]) {
if (default_route_set[unit]) {
cifdefaultroute(unit, ouraddr, hisaddr);
default_route_set[unit] = 0;
}
Expand Down
1 change: 0 additions & 1 deletion pppd/ipcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ typedef struct ipcp_options {
bool old_addrs; /* Use old (IP-Addresses) option? */
bool req_addr; /* Ask peer to send IP address? */
bool default_route; /* Assign default route through interface? */
bool replace_default_route; /* Replace default route through interface? */
bool proxy_arp; /* Make proxy ARP entry for peer? */
bool neg_vj; /* Van Jacobson Compression? */
bool old_vj; /* use old (short) form of VJ option? */
Expand Down
6 changes: 6 additions & 0 deletions pppd/ipv6cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ ipv6cp_options ipv6cp_allowoptions[NUM_PPP]; /* Options we allow peer to request
ipv6cp_options ipv6cp_hisoptions[NUM_PPP]; /* Options that we ack'd */
int no_ifaceid_neg = 0;

unsigned dfl_route6_metric = 0; /* metric of the default route to set over the PPP link */

/* local vars */
static int default_route_set[NUM_PPP]; /* Have set up a default route */
static int ipv6cp_is_up;
Expand Down Expand Up @@ -258,6 +260,10 @@ static struct option ipv6cp_option_list[] = {
"disable defaultroute6 option", OPT_ALIAS | OPT_A2CLR,
&ipv6cp_wantoptions[0].default_route },

{ "defaultroute6-metric", o_int, &dfl_route6_metric,
"Metric to use for the default route (Linux only; default 0)",
OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 },

{ "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip,
"Use (default) IPv4 addresses for both local and remote interface identifiers", 1 },
{ "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent,
Expand Down
5 changes: 0 additions & 5 deletions pppd/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ bool dryrun; /* print out option values and exit */
char *domain; /* domain name set by domain option */
int child_wait = 5; /* # seconds to wait for children at exit */
struct userenv *userenv_list; /* user environment variables */
int dfl_route_metric = -1; /* metric of the default route to set over the PPP link */

#ifdef PPP_WITH_IPV6CP
char path_ipv6up[MAXPATHLEN]; /* pathname of ipv6-up script */
Expand Down Expand Up @@ -331,10 +330,6 @@ struct option general_options[] = {
"Unset user environment variable",
OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint },

{ "defaultroute-metric", o_int, &dfl_route_metric,
"Metric to use for the default route (Linux only; -1 for default behavior)",
OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 },

{ "net-init-script", o_string, path_net_init,
"Set pathname of net-init script",
OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
Expand Down
2 changes: 1 addition & 1 deletion pppd/pppd-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ int sif6addr(int, eui64_t, eui64_t);
int cif6addr(int, eui64_t, eui64_t);
/* Remove an IPv6 address from i/f */
#endif
int sifdefaultroute(int, u_int32_t, u_int32_t, bool replace_default_rt);
int sifdefaultroute(int, u_int32_t, u_int32_t);
/* Create default route through i/f */
int cifdefaultroute(int, u_int32_t, u_int32_t);
/* Delete default route through i/f */
Expand Down
19 changes: 6 additions & 13 deletions pppd/pppd.8
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,8 @@ This entry is removed when the PPP connection is broken. This option
is privileged if the \fInodefaultroute\fR option has been specified.
.TP
.B defaultroute-metric
Define the metric of the \fIdefaultroute\fR and only add it if there
is no other default route with the same metric. With the default
value of -1, the route is only added if there is no default route at
all.
.TP
.B replacedefaultroute
This option is a flag to the defaultroute option. If defaultroute is
set and this flag is also set, pppd replaces an existing default route
with the new default route. This option is privileged.
Define the metric of the \fIdefaultroute\fR. By default the default route will
be added with a metric of 0. This option is privileged.
.TP
.B disconnect \fIscript
Execute the command specified by \fIscript\fR, by passing it to a
Expand Down Expand Up @@ -367,6 +360,10 @@ configured by kernel automatically too based on ICMPv6 Router Advertisement
packets. This option may conflict with kernel IPv6 route setup and should
be used only for broken IPv6 networks.
.TP
.B defaultroute6-metric
Define the metric of the \fIdefaultroute6\fR. By default the default route will
be added with a metric of 0. This option is privileged.
.TP
.B deflate \fInr,nt
Request that the peer compress packets that it sends, using the
Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and
Expand Down Expand Up @@ -802,10 +799,6 @@ Disable the \fIdefaultroute\fR option. The system administrator who
wishes to prevent users from adding a default route with pppd
can do so by placing this option in the /etc/ppp/options file.
.TP
.B noreplacedefaultroute
Disable the \fIreplacedefaultroute\fR option. This allows to disable a
\fIreplacedefaultroute\fR option set previously in the configuration.
.TP
.B nodefaultroute6
Disable the \fIdefaultroute6\fR option. The system administrator who
wishes to prevent users from adding a default route with pppd
Expand Down
Loading

0 comments on commit 99151ea

Please sign in to comment.