[package] update ppp to v2.4.4 (#5102)
[openwrt.git] / package / ppp / patches / 110-debian_defaultroute.patch
1 diff -Naur ppp-2.4.4.orig/pppd/ipcp.c ppp-2.4.4/pppd/ipcp.c
2 --- ppp-2.4.4.orig/pppd/ipcp.c  2009-05-09 02:55:46.000000000 -0400
3 +++ ppp-2.4.4/pppd/ipcp.c       2009-05-09 02:58:31.000000000 -0400
4 @@ -197,6 +197,14 @@
5        "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
6        &ipcp_wantoptions[0].default_route },
7  
8 +    { "replacedefaultroute", o_bool,
9 +                               &ipcp_wantoptions[0].replace_default_route,
10 +      "Replace default route", 1
11 +    },
12 +    { "noreplacedefaultroute", o_bool,
13 +                               &ipcp_allowoptions[0].replace_default_route,
14 +      "Never replace default route", OPT_A2COPY,
15 +                               &ipcp_wantoptions[0].replace_default_route },
16      { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
17        "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
18      { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
19 @@ -263,7 +271,7 @@
20      ip_active_pkt
21  };
22  
23 -static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
24 +static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool));
25  static void ipcp_script __P((char *, int));    /* Run an up/down script */
26  static void ipcp_script_done __P((void *));
27  
28 @@ -1660,7 +1668,8 @@
29      if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
30         return 0;
31      if (wo->default_route)
32 -       if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
33 +       if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
34 +               wo->replace_default_route))
35             default_route_set[u] = 1;
36      if (wo->proxy_arp)
37         if (sifproxyarp(u, wo->hisaddr))
38 @@ -1742,7 +1751,8 @@
39       */
40      if (demand) {
41         if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
42 -           ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
43 +           ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
44 +                                     wo->replace_default_route);
45             if (go->ouraddr != wo->ouraddr) {
46                 warn("Local IP address changed to %I", go->ouraddr);
47                 script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
48 @@ -1767,7 +1777,8 @@
49  
50             /* assign a default route through the interface if required */
51             if (ipcp_wantoptions[f->unit].default_route) 
52 -               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
53 +               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
54 +                       wo->replace_default_route))
55                     default_route_set[f->unit] = 1;
56  
57             /* Make a proxy ARP entry if requested. */
58 @@ -1817,7 +1828,8 @@
59  
60         /* assign a default route through the interface if required */
61         if (ipcp_wantoptions[f->unit].default_route) 
62 -           if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
63 +           if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
64 +                   wo->replace_default_route))
65                 default_route_set[f->unit] = 1;
66  
67         /* Make a proxy ARP entry if requested. */
68 @@ -1894,7 +1906,7 @@
69         sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
70         sifdown(f->unit);
71         ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
72 -                        ipcp_hisoptions[f->unit].hisaddr);
73 +                        ipcp_hisoptions[f->unit].hisaddr, 0);
74      }
75  
76      /* Execute the ip-down script */
77 @@ -1910,16 +1922,25 @@
78   * proxy arp entries, etc.
79   */
80  static void
81 -ipcp_clear_addrs(unit, ouraddr, hisaddr)
82 +ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute)
83      int unit;
84      u_int32_t ouraddr;  /* local address */
85      u_int32_t hisaddr;  /* remote address */
86 +    bool replacedefaultroute;
87  {
88      if (proxy_arp_set[unit]) {
89         cifproxyarp(unit, hisaddr);
90         proxy_arp_set[unit] = 0;
91      }
92 -    if (default_route_set[unit]) {
93 +    /* If replacedefaultroute, sifdefaultroute will be called soon
94 +     * with replacedefaultroute set and that will overwrite the current
95 +     * default route. This is the case only when doing demand, otherwise
96 +     * during demand, this cifdefaultroute would restore the old default
97 +     * route which is not what we want in this case. In the non-demand
98 +     * case, we'll delete the default route and restore the old if there
99 +     * is one saved by an sifdefaultroute with replacedefaultroute.
100 +     */
101 +    if (!replacedefaultroute && default_route_set[unit]) {
102         cifdefaultroute(unit, ouraddr, hisaddr);
103         default_route_set[unit] = 0;
104      }
105 diff -Naur ppp-2.4.4.orig/pppd/ipcp.h ppp-2.4.4/pppd/ipcp.h
106 --- ppp-2.4.4.orig/pppd/ipcp.h  2009-05-09 02:54:59.000000000 -0400
107 +++ ppp-2.4.4/pppd/ipcp.h       2009-05-09 02:58:31.000000000 -0400
108 @@ -70,6 +70,7 @@
109      bool old_addrs;            /* Use old (IP-Addresses) option? */
110      bool req_addr;             /* Ask peer to send IP address? */
111      bool default_route;                /* Assign default route through interface? */
112 +    bool replace_default_route;        /* Replace default route through interface? */
113      bool proxy_arp;            /* Make proxy ARP entry for peer? */
114      bool neg_vj;               /* Van Jacobson Compression? */
115      bool old_vj;               /* use old (short) form of VJ option? */
116 diff -Naur ppp-2.4.4.orig/pppd/pppd.8 ppp-2.4.4/pppd/pppd.8
117 --- ppp-2.4.4.orig/pppd/pppd.8  2009-05-09 02:54:59.000000000 -0400
118 +++ ppp-2.4.4/pppd/pppd.8       2009-05-09 02:58:31.000000000 -0400
119 @@ -121,6 +121,11 @@
120  This entry is removed when the PPP connection is broken.  This option
121  is privileged if the \fInodefaultroute\fR option has been specified.
122  .TP
123 +.B replacedefaultroute
124 +This option is a flag to the defaultroute option. If defaultroute is
125 +set and this flag is also set, pppd replaces an existing default route
126 +with the new default route.
127 +.TP
128  .B disconnect \fIscript
129  Execute the command specified by \fIscript\fR, by passing it to a
130  shell, after
131 @@ -706,7 +711,12 @@
132  .TP
133  .B nodefaultroute
134  Disable the \fIdefaultroute\fR option.  The system administrator who
135 -wishes to prevent users from creating default routes with pppd
136 +wishes to prevent users from adding a default route with pppd
137 +can do so by placing this option in the /etc/ppp/options file.
138 +.TP
139 +.B noreplacedefaultroute
140 +Disable the \fIreplacedefaultroute\fR option. The system administrator who
141 +wishes to prevent users from replacing a default route with pppd
142  can do so by placing this option in the /etc/ppp/options file.
143  .TP
144  .B nodeflate
145 diff -Naur ppp-2.4.4.orig/pppd/pppd.h ppp-2.4.4/pppd/pppd.h
146 --- ppp-2.4.4.orig/pppd/pppd.h  2009-05-09 02:55:46.000000000 -0400
147 +++ ppp-2.4.4/pppd/pppd.h       2009-05-09 02:58:31.000000000 -0400
148 @@ -644,7 +644,7 @@
149  int  cif6addr __P((int, eui64_t, eui64_t));
150                                 /* Remove an IPv6 address from i/f */
151  #endif
152 -int  sifdefaultroute __P((int, u_int32_t, u_int32_t));
153 +int  sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt));
154                                 /* Create default route through i/f */
155  int  cifdefaultroute __P((int, u_int32_t, u_int32_t));
156                                 /* Delete default route through i/f */
157 diff -Naur ppp-2.4.4.orig/pppd/sys-linux.c ppp-2.4.4/pppd/sys-linux.c
158 --- ppp-2.4.4.orig/pppd/sys-linux.c     2009-05-09 02:55:46.000000000 -0400
159 +++ ppp-2.4.4/pppd/sys-linux.c  2009-05-09 02:58:31.000000000 -0400
160 @@ -206,6 +206,8 @@
161  
162  static int     if_is_up;       /* Interface has been marked up */
163  static int     have_default_route;     /* Gateway for default route added */
164 +static struct  rtentry old_def_rt;     /* Old default route */
165 +static int     default_rt_repl_rest;   /* replace and restore old default rt */
166  static u_int32_t proxy_arp_addr;       /* Addr for proxy arp entry added */
167  static char proxy_arp_dev[16];         /* Device for proxy arp entry */
168  static u_int32_t our_old_addr;         /* for detecting address changes */
169 @@ -1520,6 +1522,9 @@
170         p = NULL;
171      }
172  
173 +    SET_SA_FAMILY (rt->rt_dst,     AF_INET);
174 +    SET_SA_FAMILY (rt->rt_gateway, AF_INET);
175 +
176      SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
177      SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
178      SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
179 @@ -1589,20 +1594,51 @@
180  /********************************************************************
181   *
182   * sifdefaultroute - assign a default route through the address given.
183 - */
184 -
185 -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
186 -{
187 -    struct rtentry rt;
188 -
189 -    if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
190 -       if (rt.rt_flags & RTF_GATEWAY)
191 -           error("not replacing existing default route via %I",
192 -                 SIN_ADDR(rt.rt_gateway));
193 -       else
194 + *
195 + * If the global default_rt_repl_rest flag is set, then this function
196 + * already replaced the original system defaultroute with some other
197 + * route and it should just replace the current defaultroute with
198 + * another one, without saving the current route. Use: demand mode,
199 + * when pppd sets first a defaultroute it it's temporary ppp0 addresses
200 + * and then changes the temporary addresses to the addresses for the real
201 + * ppp connection when it has come up.
202 + */
203 +
204 +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
205 +{
206 +    struct rtentry rt, tmp_rt;
207 +    struct rtentry *del_rt = NULL;
208 +
209 +    if (default_rt_repl_rest) {
210 +       /* We have already reclaced the original defaultroute, if we
211 +          are called again, we will delete the current default route
212 +          and set the new default route in this function.
213 +          - this is normally only the case the doing demand: */
214 +       if (defaultroute_exists(&tmp_rt))
215 +           del_rt = &tmp_rt;
216 +    } else if (defaultroute_exists(&old_def_rt) &&
217 +              strcmp(old_def_rt.rt_dev, ifname) != 0) {
218 +       /* We did not yet replace an existing default route, let's
219 +          check if we should save and replace a default route: */
220 +       if (old_def_rt.rt_flags & RTF_GATEWAY) {
221 +           if (!replace) {
222 +               error("not replacing existing default route via %I",
223 +                     SIN_ADDR(old_def_rt.rt_gateway));
224 +               return 0;
225 +           } else {
226 +               /* we need to copy rt_dev because we need it permanent too: */
227 +               char *tmp_dev = malloc(strlen(old_def_rt.rt_dev) + 1);
228 +               strcpy(tmp_dev, old_def_rt.rt_dev);
229 +               old_def_rt.rt_dev = tmp_dev;
230 +
231 +               notice("replacing old default route to %s [%I]",
232 +                       old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
233 +               default_rt_repl_rest = 1;
234 +               del_rt = &old_def_rt;
235 +           }
236 +       } else
237             error("not replacing existing default route through %s",
238 -                 rt.rt_dev);
239 -       return 0;
240 +                 old_def_rt.rt_dev);
241      }
242  
243      memset (&rt, 0, sizeof (rt));
244 @@ -1617,10 +1653,16 @@
245  
246      rt.rt_flags = RTF_UP;
247      if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
248 -       if ( ! ok_error ( errno ))
249 +       if (!ok_error(errno))
250             error("default route ioctl(SIOCADDRT): %m");
251         return 0;
252      }
253 +    if (default_rt_repl_rest && del_rt)
254 +        if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
255 +           if (!ok_error(errno))
256 +               error("del old default route ioctl(SIOCDELRT): %m");
257 +           return 0;
258 +        }
259  
260      have_default_route = 1;
261      return 1;
262 @@ -1649,11 +1691,21 @@
263      rt.rt_flags = RTF_UP;
264      if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
265         if (still_ppp()) {
266 -           if ( ! ok_error ( errno ))
267 +           if (!ok_error(errno))
268                 error("default route ioctl(SIOCDELRT): %m");
269             return 0;
270         }
271      }
272 +    if (default_rt_repl_rest) {
273 +       notice("restoring old default route to %s [%I]",
274 +               old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
275 +        if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
276 +           if (!ok_error(errno))
277 +               error("restore default route ioctl(SIOCADDRT): %m");
278 +           return 0;
279 +        }
280 +        default_rt_repl_rest = 0;
281 +    }
282  
283      return 1;
284  }
285 diff -Naur ppp-2.4.4.orig/pppd/sys-solaris.c ppp-2.4.4/pppd/sys-solaris.c
286 --- ppp-2.4.4.orig/pppd/sys-solaris.c   2009-05-09 02:54:59.000000000 -0400
287 +++ ppp-2.4.4/pppd/sys-solaris.c        2009-05-09 02:58:31.000000000 -0400
288 @@ -2036,12 +2036,18 @@
289   * sifdefaultroute - assign a default route through the address given.
290   */
291  int
292 -sifdefaultroute(u, l, g)
293 +sifdefaultroute(u, l, g, replace)
294      int u;
295      u_int32_t l, g;
296 +    bool replace;
297  {
298      struct rtentry rt;
299  
300 +    if (replace) {
301 +       error("replacedefaultroute not supported on this platform");
302 +       return 0;
303 +    }
304 +
305  #if defined(__USLC__)
306      g = l;                     /* use the local address as gateway */
307  #endif
308 diff -Naur ppp-2.4.4.orig/pppd/ipcp.c ppp-2.4.4/pppd/ipcp.c
309 --- ppp-2.4.4.orig/pppd/ipcp.c  2009-05-09 02:55:46.000000000 -0400
310 +++ ppp-2.4.4/pppd/ipcp.c       2009-05-09 02:58:31.000000000 -0400
311 @@ -197,6 +197,14 @@
312        "disable defaultroute option", OPT_ALIAS | OPT_A2CLR,
313        &ipcp_wantoptions[0].default_route },
314  
315 +    { "replacedefaultroute", o_bool,
316 +                               &ipcp_wantoptions[0].replace_default_route,
317 +      "Replace default route", 1
318 +    },
319 +    { "noreplacedefaultroute", o_bool,
320 +                               &ipcp_allowoptions[0].replace_default_route,
321 +      "Never replace default route", OPT_A2COPY,
322 +                               &ipcp_wantoptions[0].replace_default_route },
323      { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp,
324        "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp },
325      { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp,
326 @@ -263,7 +271,7 @@
327      ip_active_pkt
328  };
329  
330 -static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t));
331 +static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool));
332  static void ipcp_script __P((char *, int));    /* Run an up/down script */
333  static void ipcp_script_done __P((void *));
334  
335 @@ -1660,7 +1668,8 @@
336      if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
337         return 0;
338      if (wo->default_route)
339 -       if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr))
340 +       if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr,
341 +               wo->replace_default_route))
342             default_route_set[u] = 1;
343      if (wo->proxy_arp)
344         if (sifproxyarp(u, wo->hisaddr))
345 @@ -1742,7 +1751,8 @@
346       */
347      if (demand) {
348         if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) {
349 -           ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr);
350 +           ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr,
351 +                                     wo->replace_default_route);
352             if (go->ouraddr != wo->ouraddr) {
353                 warn("Local IP address changed to %I", go->ouraddr);
354                 script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0);
355 @@ -1767,7 +1777,8 @@
356  
357             /* assign a default route through the interface if required */
358             if (ipcp_wantoptions[f->unit].default_route) 
359 -               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
360 +               if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
361 +                       wo->replace_default_route))
362                     default_route_set[f->unit] = 1;
363  
364             /* Make a proxy ARP entry if requested. */
365 @@ -1817,7 +1828,8 @@
366  
367         /* assign a default route through the interface if required */
368         if (ipcp_wantoptions[f->unit].default_route) 
369 -           if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr))
370 +           if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr,
371 +                   wo->replace_default_route))
372                 default_route_set[f->unit] = 1;
373  
374         /* Make a proxy ARP entry if requested. */
375 @@ -1894,7 +1906,7 @@
376         sifnpmode(f->unit, PPP_IP, NPMODE_DROP);
377         sifdown(f->unit);
378         ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr,
379 -                        ipcp_hisoptions[f->unit].hisaddr);
380 +                        ipcp_hisoptions[f->unit].hisaddr, 0);
381      }
382  
383      /* Execute the ip-down script */
384 @@ -1910,16 +1922,25 @@
385   * proxy arp entries, etc.
386   */
387  static void
388 -ipcp_clear_addrs(unit, ouraddr, hisaddr)
389 +ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute)
390      int unit;
391      u_int32_t ouraddr;  /* local address */
392      u_int32_t hisaddr;  /* remote address */
393 +    bool replacedefaultroute;
394  {
395      if (proxy_arp_set[unit]) {
396         cifproxyarp(unit, hisaddr);
397         proxy_arp_set[unit] = 0;
398      }
399 -    if (default_route_set[unit]) {
400 +    /* If replacedefaultroute, sifdefaultroute will be called soon
401 +     * with replacedefaultroute set and that will overwrite the current
402 +     * default route. This is the case only when doing demand, otherwise
403 +     * during demand, this cifdefaultroute would restore the old default
404 +     * route which is not what we want in this case. In the non-demand
405 +     * case, we'll delete the default route and restore the old if there
406 +     * is one saved by an sifdefaultroute with replacedefaultroute.
407 +     */
408 +    if (!replacedefaultroute && default_route_set[unit]) {
409         cifdefaultroute(unit, ouraddr, hisaddr);
410         default_route_set[unit] = 0;
411      }
412 diff -Naur ppp-2.4.4.orig/pppd/ipcp.h ppp-2.4.4/pppd/ipcp.h
413 --- ppp-2.4.4.orig/pppd/ipcp.h  2009-05-09 02:54:59.000000000 -0400
414 +++ ppp-2.4.4/pppd/ipcp.h       2009-05-09 02:58:31.000000000 -0400
415 @@ -70,6 +70,7 @@
416      bool old_addrs;            /* Use old (IP-Addresses) option? */
417      bool req_addr;             /* Ask peer to send IP address? */
418      bool default_route;                /* Assign default route through interface? */
419 +    bool replace_default_route;        /* Replace default route through interface? */
420      bool proxy_arp;            /* Make proxy ARP entry for peer? */
421      bool neg_vj;               /* Van Jacobson Compression? */
422      bool old_vj;               /* use old (short) form of VJ option? */
423 diff -Naur ppp-2.4.4.orig/pppd/pppd.8 ppp-2.4.4/pppd/pppd.8
424 --- ppp-2.4.4.orig/pppd/pppd.8  2009-05-09 02:54:59.000000000 -0400
425 +++ ppp-2.4.4/pppd/pppd.8       2009-05-09 02:58:31.000000000 -0400
426 @@ -121,6 +121,11 @@
427  This entry is removed when the PPP connection is broken.  This option
428  is privileged if the \fInodefaultroute\fR option has been specified.
429  .TP
430 +.B replacedefaultroute
431 +This option is a flag to the defaultroute option. If defaultroute is
432 +set and this flag is also set, pppd replaces an existing default route
433 +with the new default route.
434 +.TP
435  .B disconnect \fIscript
436  Execute the command specified by \fIscript\fR, by passing it to a
437  shell, after
438 @@ -706,7 +711,12 @@
439  .TP
440  .B nodefaultroute
441  Disable the \fIdefaultroute\fR option.  The system administrator who
442 -wishes to prevent users from creating default routes with pppd
443 +wishes to prevent users from adding a default route with pppd
444 +can do so by placing this option in the /etc/ppp/options file.
445 +.TP
446 +.B noreplacedefaultroute
447 +Disable the \fIreplacedefaultroute\fR option. The system administrator who
448 +wishes to prevent users from replacing a default route with pppd
449  can do so by placing this option in the /etc/ppp/options file.
450  .TP
451  .B nodeflate
452 diff -Naur ppp-2.4.4.orig/pppd/pppd.h ppp-2.4.4/pppd/pppd.h
453 --- ppp-2.4.4.orig/pppd/pppd.h  2009-05-09 02:55:46.000000000 -0400
454 +++ ppp-2.4.4/pppd/pppd.h       2009-05-09 02:58:31.000000000 -0400
455 @@ -644,7 +644,7 @@
456  int  cif6addr __P((int, eui64_t, eui64_t));
457                                 /* Remove an IPv6 address from i/f */
458  #endif
459 -int  sifdefaultroute __P((int, u_int32_t, u_int32_t));
460 +int  sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt));
461                                 /* Create default route through i/f */
462  int  cifdefaultroute __P((int, u_int32_t, u_int32_t));
463                                 /* Delete default route through i/f */
464 diff -Naur ppp-2.4.4.orig/pppd/sys-linux.c ppp-2.4.4/pppd/sys-linux.c
465 --- ppp-2.4.4.orig/pppd/sys-linux.c     2009-05-09 02:55:46.000000000 -0400
466 +++ ppp-2.4.4/pppd/sys-linux.c  2009-05-09 02:58:31.000000000 -0400
467 @@ -206,6 +206,8 @@
468  
469  static int     if_is_up;       /* Interface has been marked up */
470  static int     have_default_route;     /* Gateway for default route added */
471 +static struct  rtentry old_def_rt;     /* Old default route */
472 +static int     default_rt_repl_rest;   /* replace and restore old default rt */
473  static u_int32_t proxy_arp_addr;       /* Addr for proxy arp entry added */
474  static char proxy_arp_dev[16];         /* Device for proxy arp entry */
475  static u_int32_t our_old_addr;         /* for detecting address changes */
476 @@ -1520,6 +1522,9 @@
477         p = NULL;
478      }
479  
480 +    SET_SA_FAMILY (rt->rt_dst,     AF_INET);
481 +    SET_SA_FAMILY (rt->rt_gateway, AF_INET);
482 +
483      SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
484      SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
485      SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
486 @@ -1589,20 +1594,51 @@
487  /********************************************************************
488   *
489   * sifdefaultroute - assign a default route through the address given.
490 - */
491 -
492 -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
493 -{
494 -    struct rtentry rt;
495 -
496 -    if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) {
497 -       if (rt.rt_flags & RTF_GATEWAY)
498 -           error("not replacing existing default route via %I",
499 -                 SIN_ADDR(rt.rt_gateway));
500 -       else
501 + *
502 + * If the global default_rt_repl_rest flag is set, then this function
503 + * already replaced the original system defaultroute with some other
504 + * route and it should just replace the current defaultroute with
505 + * another one, without saving the current route. Use: demand mode,
506 + * when pppd sets first a defaultroute it it's temporary ppp0 addresses
507 + * and then changes the temporary addresses to the addresses for the real
508 + * ppp connection when it has come up.
509 + */
510 +
511 +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
512 +{
513 +    struct rtentry rt, tmp_rt;
514 +    struct rtentry *del_rt = NULL;
515 +
516 +    if (default_rt_repl_rest) {
517 +       /* We have already reclaced the original defaultroute, if we
518 +          are called again, we will delete the current default route
519 +          and set the new default route in this function.
520 +          - this is normally only the case the doing demand: */
521 +       if (defaultroute_exists(&tmp_rt))
522 +           del_rt = &tmp_rt;
523 +    } else if (defaultroute_exists(&old_def_rt) &&
524 +              strcmp(old_def_rt.rt_dev, ifname) != 0) {
525 +       /* We did not yet replace an existing default route, let's
526 +          check if we should save and replace a default route: */
527 +       if (old_def_rt.rt_flags & RTF_GATEWAY) {
528 +           if (!replace) {
529 +               error("not replacing existing default route via %I",
530 +                     SIN_ADDR(old_def_rt.rt_gateway));
531 +               return 0;
532 +           } else {
533 +               /* we need to copy rt_dev because we need it permanent too: */
534 +               char *tmp_dev = malloc(strlen(old_def_rt.rt_dev) + 1);
535 +               strcpy(tmp_dev, old_def_rt.rt_dev);
536 +               old_def_rt.rt_dev = tmp_dev;
537 +
538 +               notice("replacing old default route to %s [%I]",
539 +                       old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
540 +               default_rt_repl_rest = 1;
541 +               del_rt = &old_def_rt;
542 +           }
543 +       } else
544             error("not replacing existing default route through %s",
545 -                 rt.rt_dev);
546 -       return 0;
547 +                 old_def_rt.rt_dev);
548      }
549  
550      memset (&rt, 0, sizeof (rt));
551 @@ -1617,10 +1653,16 @@
552  
553      rt.rt_flags = RTF_UP;
554      if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) {
555 -       if ( ! ok_error ( errno ))
556 +       if (!ok_error(errno))
557             error("default route ioctl(SIOCADDRT): %m");
558         return 0;
559      }
560 +    if (default_rt_repl_rest && del_rt)
561 +        if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
562 +           if (!ok_error(errno))
563 +               error("del old default route ioctl(SIOCDELRT): %m");
564 +           return 0;
565 +        }
566  
567      have_default_route = 1;
568      return 1;
569 @@ -1649,11 +1691,21 @@
570      rt.rt_flags = RTF_UP;
571      if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) {
572         if (still_ppp()) {
573 -           if ( ! ok_error ( errno ))
574 +           if (!ok_error(errno))
575                 error("default route ioctl(SIOCDELRT): %m");
576             return 0;
577         }
578      }
579 +    if (default_rt_repl_rest) {
580 +       notice("restoring old default route to %s [%I]",
581 +               old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
582 +        if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
583 +           if (!ok_error(errno))
584 +               error("restore default route ioctl(SIOCADDRT): %m");
585 +           return 0;
586 +        }
587 +        default_rt_repl_rest = 0;
588 +    }
589  
590      return 1;
591  }
592 diff -Naur ppp-2.4.4.orig/pppd/sys-solaris.c ppp-2.4.4/pppd/sys-solaris.c
593 --- ppp-2.4.4.orig/pppd/sys-solaris.c   2009-05-09 02:54:59.000000000 -0400
594 +++ ppp-2.4.4/pppd/sys-solaris.c        2009-05-09 02:58:31.000000000 -0400
595 @@ -2036,12 +2036,18 @@
596   * sifdefaultroute - assign a default route through the address given.
597   */
598  int
599 -sifdefaultroute(u, l, g)
600 +sifdefaultroute(u, l, g, replace)
601      int u;
602      u_int32_t l, g;
603 +    bool replace;
604  {
605      struct rtentry rt;
606  
607 +    if (replace) {
608 +       error("replacedefaultroute not supported on this platform");
609 +       return 0;
610 +    }
611 +
612  #if defined(__USLC__)
613      g = l;                     /* use the local address as gateway */
614  #endif