source: src/router/services/services/routing.c @ 13413

Last change on this file since 13413 was 13413, checked in by BrainSlayer, 3 years ago

alternate kill method

File size: 14.9 KB
Line 
1/*
2 * routing.c
3 *
4 * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * $Id:
21 */
22
23#include <stdlib.h>
24#include <bcmnvram.h>
25#include <shutils.h>
26#include <utils.h>
27#include <syslog.h>
28#include <signal.h>
29#include <errno.h>
30#include <wlutils.h>
31#include <services.h>
32
33#ifdef HAVE_QUAGGA
34
35int zebra_ospf_init(void);
36int zebra_bgp_init(void);
37int zebra_ripd_init(void);
38
39int zebra_init(void)
40{
41        char *sub;
42        char var[32], *next;
43
44        sub = nvram_safe_get("wk_mode");
45        foreach(var, sub, next) {
46                if (!strcmp(var, "gateway")) {
47                        printf("zebra disabled.\n");
48                        return 0;
49                } else if (!strcmp(var, "ospf")) {
50                        zebra_ospf_init();
51                        dd_syslog(LOG_INFO,
52                                  "zebra : zebra (ospf) successfully initiated\n");
53                } else if (!strcmp(var, "bgp")) {
54                        zebra_bgp_init();
55                        dd_syslog(LOG_INFO,
56                                  "zebra : zebra (ospf) successfully initiated\n");
57                } else if (!strcmp(var, "router")) {
58                        zebra_ripd_init();
59                        dd_syslog(LOG_INFO,
60                                  "zebra : zebra (router) successfully initiated\n");
61                }
62        }
63        return 0;
64}
65
66void start_quagga_writememory(void)
67{
68        FILE *in = fopen("/tmp/zebra.conf", "rb");
69
70        if (in != NULL) {
71                fseek(in, 0, SEEK_END);
72                int len = ftell(in);
73
74                rewind(in);
75                char *buf = malloc(len + 1);
76
77                fread(buf, len, 1, in);
78                buf[len] = 0;
79                fclose(in);
80                nvram_set("zebra_copt", "1");
81                nvram_set("zebra_conf", buf);
82                free(buf);
83        } else {
84                nvram_set("zebra_copt", "0");
85                nvram_unset("zebra_conf");
86        }
87        in = fopen("/tmp/ospfd.conf", "rb");
88
89        if (in != NULL) {
90                fseek(in, 0, SEEK_END);
91                int len = ftell(in);
92
93                rewind(in);
94                char *buf = malloc(len + 1);
95
96                fread(buf, len, 1, in);
97                buf[len] = 0;
98                fclose(in);
99                nvram_set("ospfd_copt", "1");
100                nvram_set("ospfd_conf", buf);
101                free(buf);
102        } else {
103                nvram_set("ospfd_copt", "0");
104                nvram_unset("ospfd_conf");
105        }
106
107        in = fopen("/tmp/bgpd.conf", "rb");
108
109        if (in != NULL) {
110                fseek(in, 0, SEEK_END);
111                int len = ftell(in);
112
113                rewind(in);
114                char *buf = malloc(len + 1);
115
116                fread(buf, len, 1, in);
117                buf[len] = 0;
118                fclose(in);
119                nvram_set("bgpd_copt", "1");
120                nvram_set("bgpd_conf", buf);
121                free(buf);
122        } else {
123                nvram_set("bgpd_copt", "0");
124                nvram_unset("bgpd_conf");
125        }
126
127        in = fopen("/tmp/ripd.conf", "rb");
128
129        if (in != NULL) {
130                fseek(in, 0, SEEK_END);
131                int len = ftell(in);
132
133                rewind(in);
134                char *buf = malloc(len + 1);
135
136                fread(buf, len, 1, in);
137                buf[len] = 0;
138                fclose(in);
139                nvram_set("ripd_copt", "1");
140                nvram_set("ripd_conf", buf);
141                free(buf);
142        } else {
143                nvram_set("ripd_copt", "0");
144                nvram_unset("ripd_conf");
145        }
146
147        nvram_commit();
148}
149
150int zebra_ospf_init(void)
151{
152        char *lf = nvram_safe_get("lan_ifname");
153        char *wf = get_wan_face();
154
155        FILE *fp;
156        int ret1, ret2, s = 0, i = 0;
157
158        /*
159         * Write configuration file based on current information
160         */
161        if (!(fp = fopen("/tmp/zebra.conf", "w"))) {
162                perror("/tmp/zebra.conf");
163                return errno;
164        }
165
166        if (nvram_match("zebra_copt", "1")) {
167                if (nvram_match("zebra_log", "1")) {
168                        fprintf(fp, "log file /var/log/zebra.log\n");
169                }
170        }
171
172        if (strlen(nvram_safe_get("zebra_conf")) > 0) {
173                fwritenvram("zebra_conf", fp);
174        }
175
176        fclose(fp);
177
178        if (!(fp = fopen("/tmp/ospfd.conf", "w"))) {
179                perror("/tmp/ospfd.conf");
180                return errno;
181        }
182
183        if (nvram_match("ospfd_copt", "1")
184            && strlen(nvram_safe_get("ospfd_conf"))) {
185                fwritenvram("ospfd_conf", fp);
186        } else {
187                fprintf(fp, "!\n");
188                // fprintf (fp, "password %s\n", nvram_safe_get ("http_passwd"));
189                // fprintf (fp, "enable password %s\n", nvram_safe_get
190                // ("http_passwd"));
191                fprintf(fp, "!\n!\n!\n");
192
193                fprintf(fp, "interface %s\n!\n", lf);
194                if (wf && strlen(wf) > 0)
195                        fprintf(fp, "interface %s\n", wf);
196
197                int cnt = get_wl_instances();
198                int c;
199
200                for (c = 0; c < cnt; c++) {
201                        if (nvram_nmatch("1", "wl%d_br1_enable", c)) {
202                                fprintf(fp, "!\n! 'Subnet' WDS bridge\n");
203                                fprintf(fp, "interface br1\n");
204                        }
205                        if (nvram_nmatch("ap", "wl%d_mode", c))
206                                for (s = 1; s <= MAX_WDS_DEVS; s++) {
207                                        char wdsdevospf[32] = { 0 };
208                                        char *dev;
209
210                                        sprintf(wdsdevospf, "wl%d_wds%d_ospf",
211                                                c, s);
212                                        dev = nvram_nget("wl%d_wds%d_if", c, s);
213
214                                        if (nvram_nmatch
215                                            ("1", "wl%d_wds%d_enable", c, s)) {
216                                                fprintf(fp, "!\n! WDS: %s\n",
217                                                        nvram_nget
218                                                        ("wl%d_wds%d_desc", c,
219                                                         s));
220                                                fprintf(fp, "interface %s\n",
221                                                        dev);
222
223                                                if (atoi
224                                                    (nvram_safe_get(wdsdevospf))
225                                                    > 0)
226                                                        fprintf(fp,
227                                                                " ip ospf cost %s\n",
228                                                                nvram_safe_get
229                                                                (wdsdevospf));
230                                        }
231                                }
232                        fprintf(fp, "!\n");
233                }
234                fprintf(fp, "router ospf\n");
235                fprintf(fp, " passive-interface lo\n");
236                fprintf(fp, " ospf router-id %s\n",
237                        nvram_safe_get("lan_ipaddr"));
238                fprintf(fp, " redistribute kernel\n");
239                fprintf(fp, " redistribute connected\n");
240                fprintf(fp, " redistribute static\n");
241                fprintf(fp, " network 0.0.0.0/0 area 0\n");     // handle all routing
242                fprintf(fp, " default-information originate\n");
243
244                for (s = 1; s <= MAX_WDS_DEVS; s++) {
245                        char wdsdevospf[32] = { 0 };
246                        sprintf(wdsdevospf, "wl_wds%d_ospf", s);
247
248                        if (atoi(nvram_safe_get(wdsdevospf)) < 0)
249                                fprintf(fp, " passive-interface %s\n",
250                                        nvram_nget("wl_wds%d_if", s));
251                }
252
253                if (nvram_match("zebra_log", "1")) {
254                        fprintf(fp, "!\n");
255                        fprintf(fp, "log file /var/log/ospf.log\n");
256                }
257
258                fprintf(fp, "!\nline vty\n!\n");
259        }
260
261        fflush(fp);
262        fclose(fp);
263
264        if (nvram_match("dyn_default", "1"))
265                while (!eval("ip", "route", "del", "default")) ;
266
267        ret1 = eval("zebra", "-d", "-f", "/tmp/zebra.conf");
268        ret2 = eval("ospfd", "-d", "-f", "/tmp/ospfd.conf");
269
270        return ret1 + ret2;
271}
272
273int zebra_ripd_init(void)
274{
275
276        char *lt = nvram_safe_get("dr_lan_tx");
277        char *lr = nvram_safe_get("dr_lan_rx");
278        char *wt = nvram_safe_get("dr_wan_tx");
279        char *wr = nvram_safe_get("dr_wan_rx");
280        char *lf = nvram_safe_get("lan_ifname");
281        char *wf = get_wan_face();
282
283        FILE *fp;
284        int ret1, ret2;
285
286        // printf("Start zebra\n");
287        if (!strcmp(lt, "0") && !strcmp(lr, "0") &&
288            !strcmp(wt, "0") && !strcmp(wr, "0")
289            && !nvram_match("zebra_copt", "1")) {
290                fprintf(stderr, "zebra disabled.\n");
291                return 0;
292        }
293
294        /*
295         * Write configuration file based on current information
296         */
297        if (!(fp = fopen("/tmp/zebra.conf", "w"))) {
298                perror("/tmp/zebra.conf");
299                return errno;
300        }
301
302        if (nvram_match("zebra_copt", "1")) {
303                if (nvram_match("zebra_log", "1")) {
304                        fprintf(fp, "log file /var/log/zebra.log\n");
305                }
306        }
307
308        if (strlen(nvram_safe_get("zebra_conf")) > 0) {
309                fwritenvram("zebra_conf", fp);
310        }
311
312        fclose(fp);
313
314        if (!(fp = fopen("/tmp/ripd.conf", "w"))) {
315                perror("/tmp/ripd.conf");
316                return errno;
317        }
318
319        if (nvram_match("ripd_copt", "1")) {
320                fwritenvram("ripd_conf", fp);
321        } else {
322
323                fprintf(fp, "router rip\n");
324                fprintf(fp, "  network %s\n", lf);
325                if (wf && strlen(wf) > 0)
326                        fprintf(fp, "  network %s\n", wf);
327                fprintf(fp, "redistribute connected\n");
328                // fprintf(fp, "redistribute kernel\n");
329                // fprintf(fp, "redistribute static\n");
330
331                fprintf(fp, "interface %s\n", lf);
332                if (strcmp(lt, "0") != 0)
333                        fprintf(fp, "  ip rip send version %s\n", lt);
334                if (strcmp(lr, "0") != 0)
335                        fprintf(fp, "  ip rip receive version %s\n", lr);
336
337                if (wf && strlen(wf) > 0)
338                        fprintf(fp, "interface %s\n", wf);
339                if (strcmp(wt, "0") != 0)
340                        fprintf(fp, "  ip rip send version %s\n", wt);
341                if (strcmp(wr, "0") != 0)
342                        fprintf(fp, "  ip rip receive version %s\n", wr);
343
344                fprintf(fp, "router rip\n");
345                if (strcmp(lt, "0") == 0)
346                        fprintf(fp, "  distribute-list private out %s\n", lf);
347                if (strcmp(lr, "0") == 0)
348                        fprintf(fp, "  distribute-list private in  %s\n", lf);
349                if (wf && strlen(wf) > 0) {
350                        if (strcmp(wt, "0") == 0)
351                                fprintf(fp,
352                                        "  distribute-list private out %s\n",
353                                        wf);
354                        if (strcmp(wr, "0") == 0)
355                                fprintf(fp,
356                                        "  distribute-list private in  %s\n",
357                                        wf);
358                }
359                fprintf(fp, "access-list private deny any\n");
360
361                // fprintf(fp, "debug rip events\n");
362                // fprintf(fp, "log file /tmp/ripd.log\n");
363                fflush(fp);
364        }
365        fclose(fp);
366
367        ret1 = eval("zebra", "-d", "-f", "/tmp/zebra.conf");
368        ret2 = eval("ripd", "-d", "-f", "/tmp/ripd.conf");
369
370        return ret1 + ret2;
371}
372
373int zebra_bgp_init(void)
374{
375
376        char *lt = nvram_safe_get("dr_lan_tx");
377        char *lr = nvram_safe_get("dr_lan_rx");
378        char *wt = nvram_safe_get("dr_wan_tx");
379        char *wr = nvram_safe_get("dr_wan_rx");
380        char *lf = nvram_safe_get("lan_ifname");
381        char *wf = get_wan_face();
382
383        FILE *fp;
384        int ret1, ret2;
385
386        if (!strcmp(lt, "0") && !strcmp(lr, "0") &&
387            !strcmp(wt, "0") && !strcmp(wr, "0")
388            && !nvram_match("zebra_copt", "1")) {
389                return 0;
390        }
391
392        /*
393         * Write configuration file based on current information
394         */
395        if (!(fp = fopen("/tmp/zebra.conf", "w"))) {
396                perror("/tmp/zebra.conf");
397                return errno;
398        }
399
400        if (nvram_match("zebra_copt", "1")) {
401                if (nvram_match("zebra_log", "1")) {
402                        fprintf(fp, "log file /var/log/zebra.log\n");
403                }
404        }
405
406        if (strlen(nvram_safe_get("zebra_conf")) > 0) {
407                fwritenvram("zebra_conf", fp);
408        }
409
410        fclose(fp);
411
412        if (!(fp = fopen("/tmp/bgpd.conf", "w"))) {
413                perror("/tmp/bgpd.conf");
414                return errno;
415        }
416        if (nvram_match("bgpd_copt", "1")) {
417                fwritenvram("bgpd_conf", fp);
418        } else {
419                fprintf(fp, "router bgp %s\n",
420                        nvram_safe_get("routing_bgp_as"));
421                fprintf(fp, "  network %s/%d\n", nvram_safe_get("lan_ipaddr"),
422                        get_net(nvram_safe_get("lan_netmask")));
423                if (wf && strlen(wf) > 0
424                    && !nvram_match("wan_ipaddr", "0.0.0.0"))
425                        fprintf(fp, "  network %s/%s\n",
426                                nvram_safe_get("wan_ipaddr"),
427                                nvram_safe_get("wan_netmask"));
428                fprintf(fp, "neighbor %s local-as %s\n", lf,
429                        nvram_safe_get("routing_bgp_as"));
430                if (wf && strlen(wf) > 0)
431                        fprintf(fp, "neighbor %s local-as %s\n", wf,
432                                nvram_safe_get("routing_bgp_as"));
433                fprintf(fp, "neighbor %s remote-as %s\n",
434                        nvram_safe_get("routing_bgp_neighbor_ip"),
435                        nvram_safe_get("routing_bgp_neighbor_as"));
436                fprintf(fp, "access-list all permit any\n");
437
438                fflush(fp);
439        }
440        fclose(fp);
441
442        ret1 = eval("zebra", "-d", "-f", "/tmp/zebra.conf");
443        ret2 = eval("bgpd", "-d", "-f", "/tmp/bgpd.conf");
444
445        return ret1 + ret2;
446}
447
448#endif
449
450#ifdef HAVE_BIRD
451int bird_init(void)
452{
453        FILE *fp;
454        int ret1;
455
456        /*
457         * compatibitly for old nvram style (site needs to be enhanced)
458         */
459        if (nvram_match("wk_mode", "gateway"))
460                return 0;
461        nvram_set("routing_ospf", "off");
462        nvram_set("routing_bgp", "off");
463        nvram_set("routing_rip2", "off");
464
465        if (nvram_match("wk_mode", "ospf"))
466                nvram_set("routing_ospf", "on");
467        if (nvram_match("wk_mode", "router"))
468                nvram_set("routing_rip2", "on");
469        if (nvram_match("wk_mode", "bgp"))
470                nvram_set("routing_bgp", "on");
471
472        if (nvram_match("dr_setting", "1")) {
473                nvram_set("routing_wan", "on");
474                nvram_set("routing_lan", "off");
475        }
476        if (nvram_match("dr_setting", "2")) {
477                nvram_set("routing_wan", "off");
478                nvram_set("routing_lan", "on");
479        }
480        if (nvram_match("dr_setting", "3")) {
481                nvram_set("routing_wan", "on");
482                nvram_set("routing_lan", "on");
483        }
484        if (nvram_match("dr_setting", "0")) {
485                nvram_set("routing_wan", "off");
486                nvram_set("routing_lan", "off");
487        }
488        // DD-WRT bird support
489        if (nvram_match("routing_rip2", "on") ||
490            nvram_match("routing_ospf", "on")
491            || nvram_match("routing_bgp", "on")) {
492                mkdir("/tmp/bird", 0744);
493                if (!(fp = fopen("/tmp/bird/bird.conf", "w"))) {
494                        perror("/tmp/bird/bird.conf");
495                        return errno;
496                }
497                fprintf(fp, "router id %s;\n", nvram_safe_get("lan_ipaddr"));
498                fprintf(fp,
499                        "protocol kernel { learn; persist; scan time 10; import all; export all; }\n");
500                fprintf(fp, "protocol device { scan time 10; } \n");
501                fprintf(fp, "protocol direct { interface \"*\";}\n");
502
503                if (nvram_match("routing_rip2", "on")) {
504
505                        fprintf(fp, "protocol rip WRT54G_rip {\n");
506                        if (nvram_match("routing_lan", "on"))
507                                fprintf(fp, "   interface \"%s\" { };\n",
508                                        nvram_safe_get("lan_ifname"));
509                        if (nvram_match("routing_wan", "on")) {
510                                if (getSTA())
511                                        fprintf(fp,
512                                                "       interface \"%s\" { };\n",
513                                                getSTA());
514                                else
515                                        fprintf(fp,
516                                                "       interface \"%s\" { };\n",
517                                                nvram_safe_get("wan_ifname"));
518
519                        }
520                        fprintf(fp, "   honor always;\n");
521                        fprintf(fp,
522                                "       import filter { print \"importing\"; accept; };\n");
523                        fprintf(fp,
524                                "       export filter { print \"exporting\"; accept; };\n");
525                        fprintf(fp, "}\n");
526
527                }
528                if (nvram_match("routing_ospf", "on")) {
529                        fprintf(fp, "protocol ospf WRT54G_ospf {\n");
530                        fprintf(fp, "area 0 {\n");
531                        if (nvram_match("routing_wan", "on"))
532                                fprintf(fp,
533                                        "interface \"%s\" { cost 1; authentication simple; password \"%s\"; };\n",
534                                        nvram_safe_get("wan_ifname"),
535                                        nvram_safe_get("http_passwd"));
536                        if (nvram_match("routing_lan", "on"))
537                                fprintf(fp,
538                                        "interface \"%s\" { cost 1; authentication simple; password \"%s\"; };\n",
539                                        nvram_safe_get("lan_ifname"),
540                                        nvram_safe_get("http_passwd"));
541                        fprintf(fp, "};\n}\n");
542                }               // if wk_mode = ospf
543
544                if (nvram_match("routing_bgp", "on")) {
545                        fprintf(fp, "protocol bgp {\n");
546                        fprintf(fp, "local as %s;\n",
547                                nvram_safe_get("routing_bgp_as"));
548                        fprintf(fp, "neighbor %s as %s;\n",
549                                nvram_safe_get("routing_bgp_neighbor_ip"),
550                                nvram_safe_get("routing_bgp_neighbor_as"));
551                        fprintf(fp, "export all;\n");
552                        fprintf(fp, "import all;\n");
553                        fprintf(fp, "}\n");
554                }
555                fflush(fp);
556                fclose(fp);
557
558                ret1 = eval("bird", "-c", "/tmp/bird/bird.conf");
559                dd_syslog(LOG_INFO,
560                          "bird : bird daemon successfully started\n");
561        }
562        return 0;
563
564}
565#endif                          /* HAVE_BIRD */
566#if defined(HAVE_BIRD) || defined(HAVE_QUAGGA)
567/*
568 * Written by Sparq in 2002/07/16
569 */
570void start_zebra(void)
571{
572
573        if (!nvram_invmatch("zebra_enable", "0"))
574                return;
575
576#ifdef HAVE_BIRD
577
578        if (bird_init() != 0)
579                return;
580
581#elif defined(HAVE_QUAGGA)
582
583        if (zebra_init() != 0)
584                return;
585
586#endif                          /* HAVE_BIRD */
587        return;
588}
589
590/*
591 * Written by Sparq in 2002/07/16
592 */
593void stop_zebra(void)
594{
595
596#ifdef HAVE_QUAGGA
597
598        if (pidof("zebra") > 0 || pidof("ripd") > 0 || pidof("ospfd") > 0
599            || pidof("bgpd") > 0) {
600                dd_syslog(LOG_INFO,
601                          "zebra : zebra (ripd and ospfd) daemon successfully stopped\n");
602                killall("zebra", SIGTERM);
603                killall("ripd", SIGTERM);
604                killall("ospfd", SIGTERM);
605                killall("bgpd", SIGTERM);
606                int maxcount = 5;
607                if ((pidof("zebra") > 0 || pidof("ripd") > 0
608                     || pidof("ospfd") > 0 || pidof("bgpd") > 0)
609                    && (maxcount--) > 0) {
610                        sleep(1);
611                }
612                if (!maxcount) {
613                        //okay. strange, now we must kill them
614                        killall("zebra", SIGKILL);
615                        killall("ripd", SIGKILL);
616                        killall("ospfd", SIGKILL);
617                        killall("bgpd", SIGKILL);
618                }
619                cprintf("done\n");
620        }
621        return;
622
623#elif defined(HAVE_BIRD)
624        if (pidof("bird") > 0) {
625                dd_syslog(LOG_INFO,
626                          "bird : bird daemon successfully stopped\n");
627                killall("bird", SIGTERM);
628
629                cprintf("done\n");
630        }
631        return;
632
633#else
634        return;
635#endif
636}
637
638#endif
Note: See TracBrowser for help on using the repository browser.