summaryrefslogtreecommitdiff
path: root/sysdep
diff options
context:
space:
mode:
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/bsd/krt-sock.c49
-rw-r--r--sysdep/cf/bsd-v6.h1
-rw-r--r--sysdep/cf/bsd.h1
-rw-r--r--sysdep/linux/netlink.c12
-rw-r--r--sysdep/unix/io.c9
-rw-r--r--sysdep/unix/krt.c12
-rw-r--r--sysdep/unix/main.c71
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);