|
18 | 18 | * as published by the Free Software Foundation; either version
|
19 | 19 | * 2 of the License, or (at your option) any later version.
|
20 | 20 | *
|
21 |
| - * Copyright (C) 2001-2017 Alexandre Cassen, <[email protected]> |
| 21 | + * Copyright (C) 2001-2024 Alexandre Cassen, <[email protected]> |
22 | 22 | */
|
23 | 23 |
|
24 | 24 | /*
|
|
36 | 36 | 6.6 946753a 15/09/23 ensure CONF_USR_DIR honours configure lib path - uses $(LIBDIR)
|
37 | 37 | deb66ac 06/11/23 revert 946753a4
|
38 | 38 | 6.7 9626923 15/11/23 change using /usr/lib/iproute2 to /usr/share/iproute2
|
| 39 | + 6.12 b43f84a 14/10/24 add rt_addrprotos.d subdirectories |
39 | 40 |
|
40 | 41 | Debian, Ubuntu, RHEL and openSUSE moved from /etc/iproute2 to /usr/share/iproute2
|
41 | 42 | Mint, Gentoo and Archlinux currently use /etc/iproute2
|
|
67 | 68 | #include <linux/if_addr.h>
|
68 | 69 | #include <dirent.h>
|
69 | 70 | #include <errno.h>
|
| 71 | +#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE |
| 72 | +#include <unistd.h> |
| 73 | +#endif |
70 | 74 |
|
71 | 75 | #include "list_head.h"
|
72 | 76 | #include "memory.h"
|
@@ -179,6 +183,12 @@ static LIST_HEAD_INITIALIZE(rt_scopes);
|
179 | 183 |
|
180 | 184 | static char ret_buf[11]; /* uint32_t in decimal */
|
181 | 185 |
|
| 186 | +#if HAVE_DECL_IFA_PROTO && defined UPDATE_RT_ADDRPROTOS_FILE |
| 187 | +static const char *created_addrprotos_file; |
| 188 | +static const char *created_addrprotos_dir; |
| 189 | +bool updated_addrprotos_file; |
| 190 | +#endif |
| 191 | + |
182 | 192 | static void
|
183 | 193 | free_rt_entry(rt_entry_t *rte)
|
184 | 194 | {
|
@@ -584,6 +594,78 @@ get_rttables_addrproto(uint32_t id)
|
584 | 594 | return get_entry(id, &rt_scopes, RT_ADDRPROTOS_FILE, rtscope_default, 255);
|
585 | 595 | }
|
586 | 596 |
|
| 597 | +#ifdef UPDATE_RT_ADDRPROTOS_FILE |
| 598 | +static void |
| 599 | +write_addrproto_config(const char *name, uint32_t val) |
| 600 | +{ |
| 601 | + char buf[256]; |
| 602 | + FILE *fp; |
| 603 | + char *v, *e; |
| 604 | + int ver_maj, ver_min, ver_rel; |
| 605 | + char *res; |
| 606 | + const char *path, *dir = NULL; |
| 607 | + bool file_exists = false; |
| 608 | + struct stat statbuf; |
| 609 | + |
| 610 | + fp = popen("ip -V", "re"); |
| 611 | + res = fgets(buf, sizeof(buf), fp); |
| 612 | + pclose(fp); |
| 613 | + |
| 614 | + if (!res) |
| 615 | + return; |
| 616 | + |
| 617 | + /* Format is: |
| 618 | + * ip utility, iproute2-5.10.0 |
| 619 | + * or |
| 620 | + * ip utility, iproute2-6.7.0, libbpf 1.2.3 |
| 621 | + */ |
| 622 | + if (!(v = strchr(buf, '-'))) |
| 623 | + return; |
| 624 | + |
| 625 | + v++; |
| 626 | + if ((e = strchr(v, ','))) |
| 627 | + *e = '\0'; |
| 628 | + sscanf(v, "%d.%d.%d", &ver_maj, &ver_min, &ver_rel); |
| 629 | + if (ver_maj >= 7 || (ver_maj == 6 && ver_min >= 12)) { |
| 630 | + dir = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d"; |
| 631 | + path = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE ".d/keepalived_private.conf" ; |
| 632 | + } else if (ver_maj == 6 && ver_min >= 3) { |
| 633 | + path = IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE; |
| 634 | + } else |
| 635 | + return; |
| 636 | + |
| 637 | + stat(IPROUTE_ETC_DIR, &statbuf); |
| 638 | + if (dir) { |
| 639 | + if (!mkdir(dir, statbuf.st_mode & ~S_IFMT)) { // This may fail if the directory already exists |
| 640 | + created_addrprotos_dir = dir; |
| 641 | + chmod(dir, statbuf.st_mode & ~S_IFMT); |
| 642 | + } |
| 643 | + } else { |
| 644 | + /* Check if rt_addrprotos file exists */ |
| 645 | + file_exists = !stat(path, &statbuf); |
| 646 | + } |
| 647 | + |
| 648 | + if (!(fp = fopen(path, "a"))) |
| 649 | + return; |
| 650 | + |
| 651 | + if (!file_exists) |
| 652 | + chmod(path, statbuf.st_mode & ~S_IFMT & ~(S_IXUSR | S_IXGRP | S_IXOTH)); |
| 653 | + |
| 654 | + if (dir || !file_exists) { |
| 655 | + fputs("# File created by keepalived - feel free to remove it\n", fp); |
| 656 | + fprintf(fp, "%u\t%s\n", val, name); |
| 657 | + } else |
| 658 | + fprintf(fp, "%u\t%s\t# entry added by keepalived - feel free to remove it\n", val, name); |
| 659 | + |
| 660 | + fclose(fp); |
| 661 | + |
| 662 | + if (!file_exists) |
| 663 | + created_addrprotos_file = path; |
| 664 | + else |
| 665 | + updated_addrprotos_file = true; |
| 666 | +} |
| 667 | +#endif |
| 668 | + |
587 | 669 | bool
|
588 | 670 | create_rttables_addrproto(const char *name, uint8_t *id)
|
589 | 671 | {
|
@@ -618,9 +700,31 @@ create_rttables_addrproto(const char *name, uint8_t *id)
|
618 | 700 |
|
619 | 701 | list_add_tail(&rte->e_list, &rt_addrprotos);
|
620 | 702 |
|
| 703 | +#ifdef UPDATE_RT_ADDRPROTOS_FILE |
| 704 | + /* Save the entry so iproute can use it */ |
| 705 | + write_addrproto_config(name, *id); |
| 706 | +#endif |
| 707 | + |
621 | 708 | return true;
|
622 | 709 | }
|
623 | 710 |
|
| 711 | +#ifdef UPDATE_RT_ADDRPROTOS_FILE |
| 712 | +void |
| 713 | +remove_created_addrprotos_file(void) |
| 714 | +{ |
| 715 | + if (created_addrprotos_file) { |
| 716 | + unlink(created_addrprotos_file); |
| 717 | + |
| 718 | + if (created_addrprotos_dir) |
| 719 | + rmdir(created_addrprotos_dir); |
| 720 | + } else if (updated_addrprotos_file) { |
| 721 | + if (system("sed -i -e '/keepalived/d' " IPROUTE_ETC_DIR "/" RT_ADDRPROTOS_FILE)) { |
| 722 | + /* Dummy to aviod unused result warning */ |
| 723 | + } |
| 724 | + } |
| 725 | +} |
| 726 | +#endif |
| 727 | + |
624 | 728 | bool
|
625 | 729 | find_rttables_addrproto(const char *name, uint8_t *id)
|
626 | 730 | {
|
|
0 commit comments