1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
--- ppp-2.4.5/pppd/options.c
+++ ppp-2.4.5/pppd/options.c
@@ -94,6 +94,7 @@
int kdebugflag = 0; /* Tell kernel to print debug messages */
int default_device = 1; /* Using /dev/tty or equivalent */
char devnam[MAXPATHLEN]; /* Device name */
+int defaultmetric = 0; /* Metric of the default route */
bool nodetach = 0; /* Don't detach from controlling tty */
bool updetach = 0; /* Detach once link is up */
int maxconnect = 0; /* Maximum connect time */
@@ -289,6 +290,10 @@
"Number of seconds to wait for child processes at exit",
OPT_PRIO },
+ { "defaultmetric", o_int, &defaultmetric,
+ "The metric of the default route",
+ OPT_LIMITS, 0, 32766 },
+
#ifdef HAVE_MULTILINK
{ "multilink", o_bool, &multilink,
"Enable multilink operation", OPT_PRIO | 1 },
--- ppp-2.4.5/pppd/pppd.8
+++ ppp-2.4.5/pppd/pppd.8
@@ -121,6 +121,9 @@
This entry is removed when the PPP connection is broken. This option
is privileged if the \fInodefaultroute\fR option has been specified.
.TP
+.B defaultmetric \fIn
+The metric of the default route configured by pppd; default is 0.
+.TP
.B disconnect \fIscript
Execute the command specified by \fIscript\fR, by passing it to a
shell, after
--- ppp-2.4.5/pppd/pppd.h
+++ ppp-2.4.5/pppd/pppd.h
@@ -276,6 +276,7 @@
extern int kdebugflag; /* Tell kernel to print debug messages */
extern int default_device; /* Using /dev/tty or equivalent */
extern char devnam[MAXPATHLEN]; /* Device name */
+extern int defaultmetric; /* Metric of the default route */
extern int crtscts; /* Use hardware flow control */
extern bool modem; /* Use modem control lines */
extern int inspeed; /* Input/Output speed requested */
--- ppp-2.4.5/pppd/sys-linux.c
+++ ppp-2.4.5/pppd/sys-linux.c
@@ -1465,7 +1465,7 @@
FILE *route_fd = (FILE *) 0;
static char route_buffer[512];
static int route_dev_col, route_dest_col, route_gw_col;
-static int route_flags_col, route_mask_col;
+static int route_flags_col, route_mask_col, route_metric_col;
static int route_num_cols;
static int open_route_table (void);
@@ -1508,6 +1508,7 @@
route_dest_col = 1;
route_gw_col = 2;
route_flags_col = 3;
+ route_metric_col = 6;
route_mask_col = 7;
route_num_cols = 8;
@@ -1527,6 +1528,8 @@
route_gw_col = col;
else if (strcasecmp(q, "flags") == 0)
route_flags_col = col;
+ else if (strcasecmp(q, "metric") == 0)
+ route_metric_col = col;
else if (strcasecmp(q, "mask") == 0)
route_mask_col = col;
else
@@ -1569,6 +1572,7 @@
rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16);
rt->rt_dev = cols[route_dev_col];
+ rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 16);
return 1;
}
@@ -1591,6 +1595,8 @@
if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
continue;
+ if (rt->rt_metric != defaultmetric) /* consider only routes with the same metric */
+ continue;
if (SIN_ADDR(rt->rt_dst) == 0L) {
result = 1;
break;
@@ -1661,6 +1667,7 @@
SIN_ADDR(rt.rt_gateway) = gateway;
rt.rt_flags = RTF_UP | RTF_GATEWAY;
+ rt.rt_metric = defaultmetric + 1; /* +1 for binary compatibility */
if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
if ( ! ok_error ( errno ))
error("default route ioctl(SIOCADDRT): %m");
@@ -1696,6 +1703,7 @@
SIN_ADDR(rt.rt_gateway) = gateway;
rt.rt_flags = RTF_UP | RTF_GATEWAY;
+ rt.rt_metric = defaultmetric + 1; /* +1 for binary compatibility */
if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
if (still_ppp()) {
if ( ! ok_error ( errno ))
|