diff options
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/bsd/krt-sock.c | 49 | ||||
-rw-r--r-- | sysdep/cf/bsd-v6.h | 1 | ||||
-rw-r--r-- | sysdep/cf/bsd.h | 1 | ||||
-rw-r--r-- | sysdep/linux/netlink.c | 12 | ||||
-rw-r--r-- | sysdep/unix/io.c | 9 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 12 | ||||
-rw-r--r-- | sysdep/unix/main.c | 71 |
7 files changed, 121 insertions, 34 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index 08dfccc8..0bc29458 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -654,17 +654,25 @@ krt_read_addr(struct ks_msg *msg) if ((masklen = ipa_mklen(imask)) < 0) { - log("Invalid masklen"); + log(L_ERR "KIF: Invalid masklen %I for %s", imask, iface->name); return; } - bzero(&ifa, sizeof(ifa)); +#ifdef IPV6 + /* Clean up embedded interface ID returned in link-local address */ - ifa.iface = iface; + if (ipa_has_link_scope(iaddr)) + _I0(iaddr) = 0xfe800000; + + if (ipa_has_link_scope(ibrd)) + _I0(ibrd) = 0xfe800000; +#endif - memcpy(&ifa.ip, &iaddr, sizeof(ip_addr)); + + bzero(&ifa, sizeof(ifa)); + ifa.iface = iface; + ifa.ip = iaddr; ifa.pxlen = masklen; - memcpy(&ifa.brd, &ibrd, sizeof(ip_addr)); scope = ipa_classify(ifa.ip); if (scope < 0) @@ -674,24 +682,10 @@ krt_read_addr(struct ks_msg *msg) } ifa.scope = scope & IADDR_SCOPE_MASK; -#ifdef IPV6 - /* Clean up embedded interface ID returned in link-local address */ - if (ipa_has_link_scope(ifa.ip)) - _I0(ifa.ip) = 0xfe800000; -#endif - -#ifdef IPV6 - /* Why not the same check also for IPv4? */ - if ((iface->flags & IF_MULTIACCESS) || (masklen != BITS_PER_IP_ADDRESS)) -#else - if (iface->flags & IF_MULTIACCESS) -#endif + if (masklen < BITS_PER_IP_ADDRESS) { ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen)); - if (masklen == BITS_PER_IP_ADDRESS) - ifa.flags |= IA_HOST; - if (masklen == (BITS_PER_IP_ADDRESS - 1)) ifa.opposite = ipa_opposite_m1(ifa.ip); @@ -699,11 +693,22 @@ krt_read_addr(struct ks_msg *msg) if (masklen == (BITS_PER_IP_ADDRESS - 2)) ifa.opposite = ipa_opposite_m2(ifa.ip); #endif + + if (iface->flags & IF_BROADCAST) + ifa.brd = ibrd; + + if (!(iface->flags & IF_MULTIACCESS)) + ifa.opposite = ibrd; } - else /* PtP iface */ + else if (!(iface->flags & IF_MULTIACCESS) && ipa_nonzero(ibrd)) { + ifa.prefix = ifa.opposite = ibrd; ifa.flags |= IA_PEER; - ifa.prefix = ifa.opposite = ifa.brd; + } + else + { + ifa.prefix = ifa.ip; + ifa.flags |= IA_HOST; } if (new) diff --git a/sysdep/cf/bsd-v6.h b/sysdep/cf/bsd-v6.h index 3403299f..47a7c7ff 100644 --- a/sysdep/cf/bsd-v6.h +++ b/sysdep/cf/bsd-v6.h @@ -13,6 +13,7 @@ #define CONFIG_MULTIPLE_TABLES #define CONFIG_SKIP_MC_BIND +#define CONFIG_NO_IFACE_BIND /* Link: sysdep/unix diff --git a/sysdep/cf/bsd.h b/sysdep/cf/bsd.h index 1101b228..5e6d03e8 100644 --- a/sysdep/cf/bsd.h +++ b/sysdep/cf/bsd.h @@ -11,6 +11,7 @@ #define CONFIG_MULTIPLE_TABLES #define CONFIG_SKIP_MC_BIND +#define CONFIG_NO_IFACE_BIND /* Link: sysdep/unix diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index f61e31a5..08dc11b6 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -7,6 +7,7 @@ */ #include <stdio.h> +#include <unistd.h> #include <fcntl.h> #include <sys/socket.h> #include <sys/uio.h> @@ -1040,11 +1041,9 @@ nl_open_async(void) sock *sk; struct sockaddr_nl sa; int fd; - static int nl_open_tried = 0; - if (nl_open_tried) + if (nl_async_sk) return; - nl_open_tried = 1; DBG("KRT: Opening async netlink socket\n"); @@ -1065,18 +1064,18 @@ nl_open_async(void) if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { log(L_ERR "Unable to bind asynchronous rtnetlink socket: %m"); + close(fd); return; } + nl_async_rx_buffer = xmalloc(NL_RX_SIZE); + sk = nl_async_sk = sk_new(krt_pool); sk->type = SK_MAGIC; sk->rx_hook = nl_async_hook; sk->fd = fd; if (sk_open(sk)) bug("Netlink: sk_open failed"); - - if (!nl_async_rx_buffer) - nl_async_rx_buffer = xmalloc(NL_RX_SIZE); } /* @@ -1097,6 +1096,7 @@ krt_sys_start(struct krt_proto *p) void krt_sys_shutdown(struct krt_proto *p UNUSED) { + nl_table_map[KRT_CF->sys.table_id] = NULL; } int diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index da8343f9..6e3f1e4d 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -1186,6 +1186,15 @@ sk_open(sock *s) port = s->sport; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) ERR("SO_REUSEADDR"); + +#ifdef CONFIG_NO_IFACE_BIND + /* Workaround missing ability to bind to an iface */ + if ((type == SK_UDP) && s->iface && ipa_zero(s->saddr)) + { + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) < 0) + ERR("SO_REUSEPORT"); + } +#endif } fill_in_sockaddr(&sa, s->saddr, s->iface, port); if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 54297921..57cfe5a4 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -730,6 +730,13 @@ krt_prune(struct krt_proto *p) /* Route rejected, should not happen (KRF_INSTALLED) but to be sure .. */ verdict = (verdict == KRF_CREATE) ? KRF_IGNORE : KRF_DELETE; } + else + { + ea_list **x = &tmpa; + while (*x) + x = &((*x)->next); + *x = new ? new->attrs->eattrs : NULL; + } } switch (verdict) @@ -839,12 +846,11 @@ static void krt_scan_timer_start(struct krt_proto *p) { if (!krt_scan_count) - { krt_scan_timer = tm_new_set(krt_pool, krt_scan, NULL, 0, KRT_CF->scan_time); - tm_start(krt_scan_timer, 0); - } krt_scan_count++; + + tm_start(krt_scan_timer, 0); } static void diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index ecf67b65..7a945826 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -474,6 +474,58 @@ cli_init_unix(uid_t use_uid, gid_t use_gid) } /* + * PID file + */ + +static char *pid_file; +static int pid_fd; + +static inline void +open_pid_file(void) +{ + if (!pid_file) + return; + + pid_fd = open(pid_file, O_WRONLY|O_CREAT, 0664); + if (pid_fd < 0) + die("Cannot create PID file %s: %m", pid_file); +} + +static inline void +write_pid_file(void) +{ + int pl, rv; + char ps[24]; + + if (!pid_file) + return; + + /* We don't use PID file for uniqueness, so no need for locking */ + + pl = bsnprintf(ps, sizeof(ps), "%ld\n", (long) getpid()); + if (pl < 0) + bug("PID buffer too small"); + + rv = ftruncate(pid_fd, 0); + if (rv < 0) + die("fruncate: %m"); + + rv = write(pid_fd, ps, pl); + if(rv < 0) + die("write: %m"); + + close(pid_fd); +} + +static inline void +unlink_pid_file(void) +{ + if (pid_file) + unlink(pid_file); +} + + +/* * Shutdown */ @@ -497,6 +549,7 @@ async_shutdown(void) void sysdep_shutdown_done(void) { + unlink_pid_file(); unlink(path_control_socket); log_msg(L_FATAL "Shutdown completed"); exit(0); @@ -549,16 +602,17 @@ signal_init(void) * Parsing of command-line arguments */ -static char *opt_list = "c:dD:ps:u:g:"; +static char *opt_list = "c:dD:ps:P:u:g:f"; static int parse_and_exit; char *bird_name; static char *use_user; static char *use_group; +static int run_in_foreground = 0; static void usage(void) { - fprintf(stderr, "Usage: %s [-c <config-file>] [-d] [-D <debug-file>] [-p] [-s <control-socket>] [-u <user>] [-g <group>]\n", bird_name); + fprintf(stderr, "Usage: %s [-c <config-file>] [-d] [-D <debug-file>] [-p] [-s <control-socket>] [-P <pid-file>] [-u <user>] [-g <group>] [-f]\n", bird_name); exit(1); } @@ -657,12 +711,18 @@ parse_args(int argc, char **argv) case 's': path_control_socket = optarg; break; + case 'P': + pid_file = optarg; + break; case 'u': use_user = optarg; break; case 'g': use_group = optarg; break; + case 'f': + run_in_foreground = 1; + break; default: usage(); } @@ -710,6 +770,9 @@ main(int argc, char **argv) if (use_uid) drop_uid(use_uid); + if (!parse_and_exit) + open_pid_file(); + protos_build(); proto_build(&proto_unix_kernel); proto_build(&proto_unix_iface); @@ -719,7 +782,7 @@ main(int argc, char **argv) if (parse_and_exit) exit(0); - if (!debug_flag) + if (!(debug_flag||run_in_foreground)) { pid_t pid = fork(); if (pid < 0) @@ -734,6 +797,8 @@ main(int argc, char **argv) dup2(0, 2); } + write_pid_file(); + signal_init(); config_commit(conf, RECONFIG_HARD, 0); |