summaryrefslogtreecommitdiffstats
path: root/main/ppp/defaultroute-metric.3.patch
blob: 2eee724c23384a95653f6ab5466a83fcb4447a0a (plain)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
Default route metric

Define the metric of the default route 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.

Olivier Mehani <olivier.mehani@nicta.com.au>
Index: ppp-2.4.4/pppd/options.c
===================================================================
--- ppp-2.4.4.orig/pppd/options.c	2006-06-18 21:26:00.000000000 +1000
+++ ppp-2.4.4/pppd/options.c	2010-04-22 17:08:38.000000000 +1000
@@ -119,6 +119,7 @@
 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 */
+int	dfl_route_metric = -1;	/* metric of the default route to set over the PPP link */
 
 #ifdef MAXOCTETS
 unsigned int  maxoctets = 0;    /* default - no limit */
@@ -281,6 +282,10 @@
       "Number of seconds to wait for child processes at exit",
       OPT_PRIO },
 
+    { "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 },
+
 #ifdef HAVE_MULTILINK
     { "multilink", o_bool, &multilink,
       "Enable multilink operation", OPT_PRIO | 1 },
Index: ppp-2.4.4/pppd/sys-linux.c
===================================================================
--- ppp-2.4.4.orig/pppd/sys-linux.c	2005-08-27 08:44:35.000000000 +1000
+++ ppp-2.4.4/pppd/sys-linux.c	2010-04-22 17:09:44.000000000 +1000
@@ -232,7 +232,7 @@
 static void close_route_table (void);
 static int open_route_table (void);
 static int read_route_table (struct rtentry *rt);
-static int defaultroute_exists (struct rtentry *rt);
+static int defaultroute_exists (struct rtentry *rt, int metric);
 static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr,
 			   char *name, int namelen);
 static void decode_version (char *buf, int *version, int *mod, int *patch);
@@ -242,6 +242,8 @@
 
 extern u_char	inpacket_buf[];	/* borrowed from main.c */
 
+extern int dfl_route_metric;
+
 /*
  * SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
  * if it exists.
@@ -1526,9 +1528,10 @@
 /********************************************************************
  *
  * defaultroute_exists - determine if there is a default route
+ * with the given metric (or negative for any)
  */
 
-static int defaultroute_exists (struct rtentry *rt)
+static int defaultroute_exists (struct rtentry *rt, int metric)
 {
     int result = 0;
 
@@ -1541,7 +1544,8 @@
 
 	if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0)
 	    continue;
-	if (SIN_ADDR(rt->rt_dst) == 0L) {
+	if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0 ||
+			 (metric >= 0 && (rt->rt_metric + 1) == metric))) {
 	    result = 1;
 	    break;
 	}
@@ -1588,13 +1592,13 @@
 {
     struct rtentry rt;
 
-    if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
+    if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
 	if (rt.rt_flags & RTF_GATEWAY)
-	    error("not replacing existing default route via %I",
-		  SIN_ADDR(rt.rt_gateway));
+	    error("not replacing existing default route via %I with metric %d",
+		  SIN_ADDR(rt.rt_gateway), dfl_route_metric);
 	else
-	    error("not replacing existing default route through %s",
-		  rt.rt_dev);
+	    error("not replacing existing default route through %s with metric %d",
+		  rt.rt_dev, dfl_route_metric);
 	return 0;
     }
 
@@ -1602,6 +1606,7 @@
     SET_SA_FAMILY (rt.rt_dst, AF_INET);
 
     rt.rt_dev = ifname;
+    rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
 
     if (kernel_version > KVERSION(2,1,0)) {
 	SET_SA_FAMILY (rt.rt_genmask, AF_INET);
@@ -1634,6 +1639,9 @@
     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
 
+    rt.rt_dev = ifname;
+    rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
+
     if (kernel_version > KVERSION(2,1,0)) {
 	SET_SA_FAMILY (rt.rt_genmask, AF_INET);
 	SIN_ADDR(rt.rt_genmask) = 0L;
Index: ppp-2.4.4/pppd/pppd.8
===================================================================
--- ppp-2.4.4.orig/pppd/pppd.8	2006-06-16 10:01:23.000000000 +1000
+++ ppp-2.4.4/pppd/pppd.8	2010-04-22 17:08:38.000000000 +1000
@@ -121,6 +121,12 @@
 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 disconnect \fIscript
 Execute the command specified by \fIscript\fR, by passing it to a
 shell, after