From f2ae2badff37c008ba8217a12f8ee6dc6a3c5a39 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 7 Apr 2016 12:20:45 +0200 Subject: [PATCH 01/13] Main: Add local option Add option that changes default paths for config file and control socket to the current working directory. --- client/client.c | 10 ++++++++-- doc/bird.sgml | 5 +++++ lib/string.h | 6 ++++++ sysdep/unix/main.c | 16 +++++++++++++--- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/client/client.c b/client/client.c index b938f344..4075b9e6 100644 --- a/client/client.c +++ b/client/client.c @@ -37,7 +37,7 @@ #define SERVER_READ_BUF_LEN 4096 -static char *opt_list = "s:vr"; +static char *opt_list = "s:vrl"; static int verbose, restricted, once; static char *init_cmd; @@ -59,13 +59,14 @@ int term_lns, term_cls; static void usage(char *name) { - fprintf(stderr, "Usage: %s [-s ] [-v] [-r]\n", name); + fprintf(stderr, "Usage: %s [-s ] [-v] [-r] [-l]\n", name); exit(1); } static void parse_args(int argc, char **argv) { + int server_changed = 0; int c; while ((c = getopt(argc, argv, opt_list)) >= 0) @@ -73,6 +74,7 @@ parse_args(int argc, char **argv) { case 's': server_path = optarg; + server_changed = 1; break; case 'v': verbose++; @@ -80,6 +82,10 @@ parse_args(int argc, char **argv) case 'r': restricted = 1; break; + case 'l': + if (!server_changed) + server_path = xbasename(server_path); + break; default: usage(argv[0]); } diff --git a/doc/bird.sgml b/doc/bird.sgml index 5e5aeee4..5e943d7c 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -171,6 +171,11 @@ BIRD executable by configuring out routing protocols you don't use, and -f run bird in foreground. + -l + look for a configuration file and a communication socket in the current + working directory instead of in default system paths. However, paths + specified by options -R apply graceful restart recovery after start. diff --git a/lib/string.h b/lib/string.h index 218f7b1c..0f249d37 100644 --- a/lib/string.h +++ b/lib/string.h @@ -24,4 +24,10 @@ void buffer_puts(buffer *buf, const char *str); int patmatch(const byte *pat, const byte *str); +static inline char *xbasename(const char *str) +{ + char *s = strrchr(str, '/'); + return s ? s+1 : (char *) str; +} + #endif diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c index 5d5586a0..11a4acc6 100644 --- a/sysdep/unix/main.c +++ b/sysdep/unix/main.c @@ -617,7 +617,7 @@ signal_init(void) * Parsing of command-line arguments */ -static char *opt_list = "c:dD:ps:P:u:g:fR"; +static char *opt_list = "c:dD:ps:P:u:g:flR"; static int parse_and_exit; char *bird_name; static char *use_user; @@ -627,7 +627,7 @@ static int run_in_foreground = 0; static void usage(void) { - fprintf(stderr, "Usage: %s [-c ] [-d] [-D ] [-p] [-s ] [-P ] [-u ] [-g ] [-f] [-R]\n", bird_name); + fprintf(stderr, "Usage: %s [-c ] [-d] [-D ] [-p] [-s ] [-P ] [-u ] [-g ] [-f] [-l] [-R]\n", bird_name); exit(1); } @@ -677,7 +677,7 @@ get_gid(const char *s) if (!s) return 0; - + errno = 0; rv = strtol(s, &endptr, 10); @@ -694,6 +694,8 @@ get_gid(const char *s) static void parse_args(int argc, char **argv) { + int config_changed = 0; + int socket_changed = 0; int c; bird_name = get_bird_name(argv[0], "bird"); @@ -712,6 +714,7 @@ parse_args(int argc, char **argv) { case 'c': config_name = optarg; + config_changed = 1; break; case 'd': debug_flag |= 1; @@ -725,6 +728,7 @@ parse_args(int argc, char **argv) break; case 's': path_control_socket = optarg; + socket_changed = 1; break; case 'P': pid_file = optarg; @@ -738,6 +742,12 @@ parse_args(int argc, char **argv) case 'f': run_in_foreground = 1; break; + case 'l': + if (!config_changed) + config_name = xbasename(config_name); + if (!socket_changed) + path_control_socket = xbasename(path_control_socket); + break; case 'R': graceful_restart_recovery(); break; From e90dd656cc9126e1fbcc45fb77a10bf1baa2a1b5 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Fri, 8 Apr 2016 15:10:57 +0200 Subject: [PATCH 02/13] Direct: Implement check link for direct protocol When enabled, direct protocol generates routes only if the underlying link state is up. --- doc/bird.sgml | 8 +++++++- nest/config.Y | 1 + nest/rt-dev.c | 28 +++++++++++++++++++++++++++- nest/rt-dev.h | 1 + 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index 5e943d7c..829b148a 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -2155,7 +2155,7 @@ conditions, because a lower priority IGP route for the same network is not exported to the kernel routing table. This is an issue on BSD systems only, as on Linux systems BIRD cannot change non-BIRD route in the kernel routing table. -

The only configurable thing about direct is what interfaces it watches: +

There are just few configuration options for the Direct protocol:

interface @@ -2166,6 +2166,12 @@ on Linux systems BIRD cannot change non-BIRD route in the kernel routing table. interfaces), just use this clause. See common option for detailed description. The Direct protocol uses extended interface clauses. + + check link + If enabled, a hardware link state (reported by OS) is taken into + consideration. Routes for directly connected networks are generated only + if link up is reported and they are withdrawn when link disappears + (e.g., an ethernet cable is unplugged). Default value is no.

Direct device routes don't contain any specific attributes. diff --git a/nest/config.Y b/nest/config.Y index 87827c10..4566971f 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -335,6 +335,7 @@ dev_proto: dev_proto_start proto_name '{' | dev_proto proto_item ';' | dev_proto dev_iface_patt ';' + | dev_proto CHECK LINK bool ';' { DIRECT_CFG->check_link = $4; } ; dev_iface_init: diff --git a/nest/rt-dev.c b/nest/rt-dev.c index f6bc1432..ed6c06af 100644 --- a/nest/rt-dev.c +++ b/nest/rt-dev.c @@ -64,6 +64,9 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad) DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip); + if (P->check_link && !(ad->iface->flags & IF_LINK_UP)) + return; + /* Use iface ID as local source ID */ struct rte_src *src = rt_get_source(p, ad->iface->index); @@ -85,11 +88,31 @@ dev_ifa_notify(struct proto *p, unsigned c, struct ifa *ad) } } +static void +dev_if_notify(struct proto *p, uint c, struct iface *iface) +{ + struct rt_dev_config *cf = (void *) p->cf; + + if (c & (IF_CHANGE_UP | IF_CHANGE_DOWN)) + return; + + if ((c & IF_CHANGE_LINK) && cf->check_link) + { + uint ac = (iface->flags & IF_LINK_UP) ? IF_CHANGE_UP : IF_CHANGE_DOWN; + + struct ifa *a; + WALK_LIST(a, iface->addrs) + dev_ifa_notify(p, ac, a); + } +} + + static struct proto * dev_init(struct proto_config *c) { struct proto *p = proto_new(c, sizeof(struct proto)); + p->if_notify = dev_if_notify; p->ifa_notify = dev_ifa_notify; return p; } @@ -100,7 +123,8 @@ dev_reconfigure(struct proto *p, struct proto_config *new) struct rt_dev_config *o = (struct rt_dev_config *) p->cf; struct rt_dev_config *n = (struct rt_dev_config *) new; - return iface_patts_equal(&o->iface_list, &n->iface_list, NULL); + return iface_patts_equal(&o->iface_list, &n->iface_list, NULL) && + (o->check_link == n->check_link); } static void @@ -115,6 +139,8 @@ dev_copy_config(struct proto_config *dest, struct proto_config *src) * old nodes cannot be modified (although they contain internal lists). */ cfg_copy_list(&d->iface_list, &s->iface_list, sizeof(struct iface_patt)); + + d->check_link = s->check_link; } struct protocol proto_device = { diff --git a/nest/rt-dev.h b/nest/rt-dev.h index c36d0742..191b9a02 100644 --- a/nest/rt-dev.h +++ b/nest/rt-dev.h @@ -12,6 +12,7 @@ struct rt_dev_config { struct proto_config c; list iface_list; /* list of struct iface_patt */ + int check_link; }; #endif From 43fc6bb0fb720762f12124076e2241855741ceb5 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Mon, 11 Apr 2016 00:41:10 +0200 Subject: [PATCH 03/13] Documentation update --- doc/bird.sgml | 98 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 76 insertions(+), 22 deletions(-) diff --git a/doc/bird.sgml b/doc/bird.sgml index 829b148a..653e0bb5 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -173,7 +173,7 @@ BIRD executable by configuring out routing protocols you don't use, and -l look for a configuration file and a communication socket in the current - working directory instead of in default system paths. However, paths + working directory instead of in default system locations. However, paths specified by options -R @@ -717,6 +717,10 @@ This argument can be omitted if there exists only a single instance. Show router status, that is BIRD version, uptime and time from last reconfiguration. + show interfaces [summary] + Show the list of interfaces. For each interface, print its type, state, + MTU and addresses assigned. + show protocols [all] Show list of protocol instances along with tables they are connected to and protocol status, possibly giving verbose information, if show rip interfaces [ + Show detailed information about RIP interfaces. + + show rip neighbors [ + Show a list of RIP neighbors and associated state. + show static [ Show detailed information about static routes. show bfd sessions [ Show information about BFD sessions. - show interfaces [summary] - Show the list of interfaces. For each interface, print its type, state, - MTU and addresses assigned. - show symbols [table|filter|function|protocol|template|roa| Show the list of symbols defined in the configuration (names of protocols, routing tables etc.). @@ -3376,6 +3382,11 @@ protocol rip [<name>] { RIP, the option is not supported for RIPng, as no further versions are defined. + version only + Regardless of RIP version configured for the interface, BIRD accepts + incoming packets of any RIP version. This option restrict accepted + packets to the configured version. Default: no. + split horizon Split horizon is a scheme for preventing routing loops. When split horizon is active, routes are not regularly propagated back to the @@ -3520,7 +3531,7 @@ default route to prevent routing loops). packets to a neighboring router, multipath routes specifying several (possibly weighted) neighboring routers, device routes specifying forwarding to hosts on a directly connected network, recursive routes computing their nexthops by doing -route table lookups for a given IP and special routes (sink, blackhole etc.) +route table lookups for a given IP, and special routes (sink, blackhole etc.) which specify a special action to be done instead of forwarding the packet.

When the particular destination is not available (the interface is down or @@ -3528,8 +3539,26 @@ the next hop of the route is not a neighbor at the moment), Static just uninstalls the route from the table it is connected to and adds it again as soon as the destination becomes adjacent again. -

The Static protocol does not have many configuration options. The definition -of the protocol contains mainly a list of static routes: +

There are three classes of definitions in Static protocol configuration -- +global options, static route definitions, and per-route options. Usually, the +definition of the protocol contains mainly a list of static routes. + +

Global options: + + + check link + If set, hardware link states of network interfaces are taken into + consideration. When link disappears (e.g. ethernet cable is unplugged), + static routes directing to that interface are removed. It is possible + that some hardware drivers or platforms do not implement this feature. + Default: off. + + igp table + Specifies a table that is used for route table lookups of recursive + routes. Default: the same table as the protocol is connected to. + + +

Route definitions (each may also contain a block of per-route options): route @@ -3537,7 +3566,7 @@ of the protocol contains mainly a list of static routes: interface can be specified as a part of the address (e.g., route + route Static multipath route. Contains several nexthops (gateways), possibly with their weights. @@ -3553,17 +3582,33 @@ of the protocol contains mainly a list of static routes: Special routes specifying to silently drop the packet, return it as unreachable or return it as administratively prohibited. First two targets are also known as - check link - If set, hardware link states of network interfaces are taken into - consideration. When link disappears (e.g. ethernet cable is unplugged), - static routes directing to that interface are removed. It is possible - that some hardware drivers or platforms do not implement this feature. - Default: off. +

Per-route options: - igp table - Specifies a table that is used for route table lookups of recursive - routes. Default: the same table as the protocol is connected to. + + bfd + The Static protocol could use BFD protocol for next hop liveness + detection. If enabled, a BFD session to the route next hop is created + and the static route is BFD-controlled -- the static route is announced + only if the next hop liveness is confirmed by BFD. If the BFD session + fails, the static route is removed. Note that this is a bit different + compared to other protocols, which may use BFD as an advisory mechanism + for fast failure detection but ignores it if a BFD session is not even + established. + + This option can be used for static routes with a direct next hop, or + also for for individual next hops in a static multipath route (see + above). Note that BFD protocol also has to be configured, see + section for details. Default value is no. + + + This is a special option that allows filter expressions to be configured + on per-route basis. Can be used multiple times. These expressions are + evaluated when the route is originated, similarly to the import filter + of the static protocol. This is especially useful for configuring route + attributes, e.g.,

Static routes have no specific attributes. @@ -3572,14 +3617,23 @@ of the protocol contains mainly a list of static routes:

protocol static { - table testable; # Connect to a non-default routing table + table testable; # Connect to a non-default routing table + check link; # Advertise routes only if link is up route 0.0.0.0/0 via 198.51.100.130; # Default route - route 10.0.0.0/8 multipath # Multipath route + route 10.0.0.0/8 multipath # Multipath route via 198.51.100.10 weight 2 - via 198.51.100.20 + via 198.51.100.20 bfd # BFD-controlled next hop via 192.0.2.1; route 203.0.113.0/24 unreachable; # Sink route - route 10.2.0.0/24 via "arc0"; # Secondary network + route 10.2.0.0/24 via "arc0"; # Secondary network + route 192.168.10.0/24 via 198.51.100.100 { + ospf_metric1 = 20; # Set extended attribute + } + route 192.168.10.0/24 via 198.51.100.100 { + ospf_metric2 = 100; # Set extended attribute + ospf_tag = 2; # Set extended attribute + bfd; # BFD-controlled route + } } From a7baa09862e6b4856cd66197c6bd74c7df336b8f Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Wed, 13 Apr 2016 14:30:28 +0200 Subject: [PATCH 04/13] BSD: Add the IPsec SA/SP database entries control Add code for manipulation with TCP-MD5 keys in the IPsec SA/SP database at FreeBSD systems. Now, BGP MD5 authentication (RFC 2385) keys are handled automatically on both Linux and FreeBSD. Based on patches from Pavel Tvrdik. --- doc/bird.sgml | 17 ++++- lib/socket.h | 2 +- proto/bgp/bgp.c | 6 +- proto/bgp/bgp.h | 1 + proto/bgp/config.Y | 4 +- sysdep/bsd/Modules | 1 + sysdep/bsd/setkey.h | 170 +++++++++++++++++++++++++++++++++++++++++++ sysdep/bsd/sysio.h | 28 +++---- sysdep/linux/sysio.h | 6 +- sysdep/unix/io.c | 25 +++++-- 10 files changed, 226 insertions(+), 34 deletions(-) create mode 100644 sysdep/bsd/setkey.h diff --git a/doc/bird.sgml b/doc/bird.sgml index 653e0bb5..1a5fbaff 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1764,9 +1764,20 @@ using the following configuration parameters: only. Default: disabled. password - Use this password for MD5 authentication of BGP sessions. Default: no - authentication. Password has to be set by external utility - (e.g. setkey(8)) on BSD systems. + Use this password for MD5 authentication of BGP sessions (RFC 2385). + When used on BSD systems, see also setkey + On BSD systems, keys for TCP MD5 authentication are stored in the global + SA/SP database, which can be accessed by external utilities (e.g. + setkey(8)). BIRD configures security associations in the SA/SP database + automatically based on passive Standard BGP behavior is both initiating outgoing connections and diff --git a/lib/socket.h b/lib/socket.h index 0327e9e5..6babfa7b 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -87,7 +87,7 @@ int sk_leave_group(sock *s, ip_addr maddr); /* Leave multicast group on sk iface int sk_setup_broadcast(sock *s); int sk_set_ttl(sock *s, int ttl); /* Set transmit TTL for given socket */ int sk_set_min_ttl(sock *s, int ttl); /* Set minimal accepted TTL for given socket */ -int sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd); +int sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd, int setkey); int sk_set_ipv6_checksum(sock *s, int offset); int sk_set_icmp6_filter(sock *s, int p1, int p2); void sk_log_error(sock *s, const char *p); diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c index 94c8e5c2..2014525e 100644 --- a/proto/bgp/bgp.c +++ b/proto/bgp/bgp.c @@ -121,7 +121,8 @@ bgp_open(struct bgp_proto *p) bgp_counter++; if (p->cf->password) - if (sk_set_md5_auth(bgp_listen_sk, p->cf->remote_ip, p->cf->iface, p->cf->password) < 0) + if (sk_set_md5_auth(bgp_listen_sk, p->cf->source_addr, p->cf->remote_ip, + p->cf->iface, p->cf->password, p->cf->setkey) < 0) { sk_log_error(bgp_listen_sk, p->p.name); bgp_close(p, 0); @@ -191,7 +192,8 @@ bgp_close(struct bgp_proto *p, int apply_md5) bgp_counter--; if (p->cf->password && apply_md5) - if (sk_set_md5_auth(bgp_listen_sk, p->cf->remote_ip, p->cf->iface, NULL) < 0) + if (sk_set_md5_auth(bgp_listen_sk, p->cf->source_addr, p->cf->remote_ip, + p->cf->iface, NULL, p->cf->setkey) < 0) sk_log_error(bgp_listen_sk, p->p.name); if (!bgp_counter) diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index 274794f1..b1cca2d9 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -51,6 +51,7 @@ struct bgp_config { int add_path; /* Use ADD-PATH extension [draft] */ int allow_local_as; /* Allow that number of local ASNs in incoming AS_PATHs */ int gr_mode; /* Graceful restart mode (BGP_GR_*) */ + int setkey; /* Set MD5 password to system SA/SP database */ unsigned gr_time; /* Graceful restart timeout */ unsigned connect_delay_time; /* Minimum delay between connect attempts */ unsigned connect_retry_time; /* Timeout for connect attempts */ diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 85b93a6b..f3ba0e16 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -27,7 +27,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, INTERPRET, COMMUNITIES, BGP_ORIGINATOR_ID, BGP_CLUSTER_LIST, IGP, TABLE, GATEWAY, DIRECT, RECURSIVE, MED, TTL, SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX, GRACEFUL, RESTART, AWARE, - CHECK, LINK, PORT, EXTENDED, MESSAGES) + CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY) CF_GRAMMAR @@ -54,6 +54,7 @@ bgp_proto_start: proto_start BGP { BGP_CFG->default_local_pref = 100; BGP_CFG->gr_mode = BGP_GR_AWARE; BGP_CFG->gr_time = 120; + BGP_CFG->setkey = 1; } ; @@ -112,6 +113,7 @@ bgp_proto: | bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; } | bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; } | bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; } + | bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; } | bgp_proto ROUTE LIMIT expr ';' { this_proto->in_limit = cfg_allocz(sizeof(struct proto_limit)); this_proto->in_limit->limit = $4; diff --git a/sysdep/bsd/Modules b/sysdep/bsd/Modules index 96455db7..39db88e9 100644 --- a/sysdep/bsd/Modules +++ b/sysdep/bsd/Modules @@ -2,3 +2,4 @@ krt-sock.c krt-sock.Y krt-sys.h sysio.h +setkey.h diff --git a/sysdep/bsd/setkey.h b/sysdep/bsd/setkey.h new file mode 100644 index 00000000..b417faca --- /dev/null +++ b/sysdep/bsd/setkey.h @@ -0,0 +1,170 @@ +/* + * BIRD -- Manipulation the IPsec SA/SP database using setkey(8) utility + * + * (c) 2016 CZ.NIC z.s.p.o. + */ + +#include +#include +#include +#include +#include + +#include "nest/bird.h" +#include "lib/unix.h" + + +/* + * Open a socket for manage the IPsec SA/SP database entries + */ +static int +setkey_open_socket(void) +{ + int s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2); + if (s < 0) + { + log(L_ERR "SETKEY: socket: %m"); + return -1; + } + + return s; +} + +static int +setkey_send(struct sadb_msg *msg, uint len) +{ + int s = setkey_open_socket(); + if (s < 0) + return -1; + + if (msg->sadb_msg_type == SADB_ADD) + { + /* Delete possible current key in the IPsec SA/SP database */ + msg->sadb_msg_type = SADB_DELETE; + send(s, msg, len, 0); + msg->sadb_msg_type = SADB_ADD; + } + + if (send(s, msg, len, 0) < 0) + { + log(L_ERR "SETKEY: send: %m"); + close(s); + return -1; + } + + close(s); + return 0; +} + +/* + * Perform setkey(8)-like operation for set the password for TCP MD5 Signature. + * Could be called with SABD_ADD or SADB_DELETE argument. Note that SADB_ADD + * argument is internally processed as a pair of SADB_ADD and SADB_DELETE + * operations to implement replace. + */ +static int +setkey_md5(sockaddr *src, sockaddr *dst, char *passwd, uint type) +{ + uint passwd_len = passwd ? strlen(passwd) : 0; + + uint total = + sizeof(struct sadb_msg) + + sizeof(struct sadb_key) + PFKEY_ALIGN8(passwd_len) + + sizeof(struct sadb_sa) + + sizeof(struct sadb_x_sa2) + + sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa.sa_len) + + sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa.sa_len); + + char *buf = alloca(total); + char *pos = buf; + uint len; + + memset(buf, 0, total); + + struct sadb_msg *msg = (void *) pos; + len = sizeof(struct sadb_msg); + msg->sadb_msg_version = PF_KEY_V2; + msg->sadb_msg_type = type; + msg->sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE; + msg->sadb_msg_len = 0; /* Fix it later */ + msg->sadb_msg_pid = getpid(); + pos += len; + + /* Set authentication algorithm and password */ + struct sadb_key *key = (void *) pos; + len = sizeof(struct sadb_key) + PFKEY_ALIGN8(passwd_len); + key->sadb_key_len = PFKEY_UNIT64(len); + key->sadb_key_exttype = SADB_EXT_KEY_AUTH; + key->sadb_key_bits = passwd_len * 8; + memcpy(pos + sizeof(struct sadb_key), passwd, passwd_len); + pos += len; + + struct sadb_sa *sa = (void *) pos; + len = sizeof(struct sadb_sa); + sa->sadb_sa_len = PFKEY_UNIT64(len); + sa->sadb_sa_exttype = SADB_EXT_SA; + sa->sadb_sa_spi = htonl((u32) TCP_SIG_SPI); + sa->sadb_sa_auth = SADB_X_AALG_TCP_MD5; + sa->sadb_sa_encrypt = SADB_EALG_NONE; + sa->sadb_sa_flags = SADB_X_EXT_CYCSEQ; + pos += len; + + struct sadb_x_sa2 *sa2 = (void *) pos; + len = sizeof(struct sadb_x_sa2); + sa2->sadb_x_sa2_len = PFKEY_UNIT64(len); + sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2; + sa2->sadb_x_sa2_mode = IPSEC_MODE_ANY; + pos += len; + + /* Set source address */ + struct sadb_address *saddr = (void *) pos; + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa.sa_len); + saddr->sadb_address_len = PFKEY_UNIT64(len); + saddr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; + saddr->sadb_address_proto = IPSEC_ULPROTO_ANY; + saddr->sadb_address_prefixlen = MAX_PREFIX_LENGTH; + memcpy(pos + sizeof(struct sadb_address), &src->sa, src->sa.sa_len); + pos += len; + + /* Set destination address */ + struct sadb_address *daddr = (void *) pos; + len = sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa.sa_len); + daddr->sadb_address_len = PFKEY_UNIT64(len); + daddr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; + daddr->sadb_address_proto = IPSEC_ULPROTO_ANY; + daddr->sadb_address_prefixlen = MAX_PREFIX_LENGTH; + memcpy(pos + sizeof(struct sadb_address), &dst->sa, dst->sa.sa_len); + pos += len; + + len = pos - buf; + msg->sadb_msg_len = PFKEY_UNIT64(len); + + return setkey_send(msg, len); +} + +/* + * Manipulation with the IPsec SA/SP database + */ +static int +sk_set_md5_in_sasp_db(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd) +{ + sockaddr src, dst; + sockaddr_fill(&src, s->af, local, ifa, 0); + sockaddr_fill(&dst, s->af, remote, ifa, 0); + + if (passwd && *passwd) + { + int len = strlen(passwd); + if (len > TCP_KEYLEN_MAX) + ERR_MSG("The password for TCP MD5 Signature is too long"); + + if (setkey_md5(&src, &dst, passwd, SADB_ADD) < 0) + ERR_MSG("Cannot add TCP-MD5 password into the IPsec SA/SP database"); + } + else + { + if (setkey_md5(&src, &dst, NULL, SADB_DELETE) < 0) + ERR_MSG("Cannot delete TCP-MD5 password from the IPsec SA/SP database"); + } + return 0; +} diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h index c82d7a1e..6c20733f 100644 --- a/sysdep/bsd/sysio.h +++ b/sysdep/bsd/sysio.h @@ -189,30 +189,26 @@ sk_prepare_ip_header(sock *s, void *hdr, int dlen) #ifndef TCP_KEYLEN_MAX #define TCP_KEYLEN_MAX 80 #endif + #ifndef TCP_SIG_SPI #define TCP_SIG_SPI 0x1000 #endif -/* - * FIXME: Passwords has to be set by setkey(8) command. This is the same - * behaviour like Quagga. We need to add code for SA/SP entries - * management. - */ +#if defined(__FreeBSD__) +#define USE_MD5SIG_SETKEY +#include "lib/setkey.h" +#endif int -sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd) +sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd, int setkey UNUSED) { - int enable = 0; - - if (passwd && *passwd) - { - int len = strlen(passwd); - enable = TCP_SIG_SPI; - - if (len > TCP_KEYLEN_MAX) - ERR_MSG("MD5 password too long"); - } +#ifdef USE_MD5SIG_SETKEY + if (setkey) + if (sk_set_md5_in_sasp_db(s, local, remote, ifa, passwd) < 0) + return -1; +#endif + int enable = (passwd && *passwd) ? TCP_SIG_SPI : 0; if (setsockopt(s->fd, IPPROTO_TCP, TCP_MD5SIG, &enable, sizeof(enable)) < 0) { if (errno == ENOPROTOOPT) diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index c1561cbf..58644417 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -179,19 +179,19 @@ sk_prepare_cmsgs4(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen) */ int -sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd) +sk_set_md5_auth(sock *s, ip_addr local UNUSED, ip_addr remote, struct iface *ifa, char *passwd, int setkey UNUSED) { struct tcp_md5sig md5; memset(&md5, 0, sizeof(md5)); - sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, a, ifa, 0); + sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0); if (passwd) { int len = strlen(passwd); if (len > TCP_MD5SIG_MAXKEYLEN) - ERR_MSG("MD5 password too long"); + ERR_MSG("The password for TCP MD5 Signature is too long"); md5.tcpm_keylen = len; memcpy(&md5.tcpm_key, passwd, len); diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 5955dbfe..d918d321 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -951,23 +951,32 @@ sk_set_min_ttl(sock *s, int ttl) /** * sk_set_md5_auth - add / remove MD5 security association for given socket * @s: socket - * @a: IP address of the other side + * @local: IP address of local side + * @remote: IP address of remote side * @ifa: Interface for link-local IP address - * @passwd: password used for MD5 authentication + * @passwd: Password used for MD5 authentication + * @setkey: Update also system SA/SP database * - * In TCP MD5 handling code in kernel, there is a set of pairs (address, - * password) used to choose password according to address of the other side. - * This function is useful for listening socket, for active sockets it is enough - * to set s->password field. + * In TCP MD5 handling code in kernel, there is a set of security associations + * used for choosing password and other authentication parameters according to + * the local and remote address. This function is useful for listening socket, + * for active sockets it may be enough to set s->password field. * * When called with passwd != NULL, the new pair is added, * When called with passwd == NULL, the existing pair is removed. * + * Note that while in Linux, the MD5 SAs are specific to socket, in BSD they are + * stored in global SA/SP database (but the behavior also must be enabled on + * per-socket basis). In case of multiple sockets to the same neighbor, the + * socket-specific state must be configured for each socket while global state + * just once per src-dst pair. The @setkey argument controls whether the global + * state (SA/SP database) is also updated. + * * Result: 0 for success, -1 for an error. */ int -sk_set_md5_auth(sock *s, ip_addr a, struct iface *ifa, char *passwd) +sk_set_md5_auth(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd, int setkey) { DUMMY; } #endif @@ -1437,7 +1446,7 @@ sk_open(sock *s) } if (s->password) - if (sk_set_md5_auth(s, s->daddr, s->iface, s->password) < 0) + if (sk_set_md5_auth(s, s->saddr, s->daddr, s->iface, s->password, 0) < 0) goto err; switch (s->type) From 937e75d8f1d203b637ba0ea050026f9af92485f3 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 28 Apr 2016 18:01:40 +0200 Subject: [PATCH 05/13] Add the Babel routing protocol (RFC 6126) This patch implements the IPv6 subset of the Babel routing protocol. Based on the patch from Toke Hoiland-Jorgensen, with some heavy modifications and bugfixes. Thanks to Toke Hoiland-Jorgensen for the original patch. --- configure.in | 3 + doc/bird.sgml | 96 ++ doc/reply_codes | 3 + lib/birdlib.h | 1 + lib/bitops.h | 3 +- lib/ip.h | 1 + lib/printf.c | 31 +- lib/string.h | 2 + nest/proto.c | 3 + nest/protocol.h | 2 +- nest/route.h | 11 +- proto/Doc | 1 + proto/babel/Doc | 2 + proto/babel/Makefile | 5 + proto/babel/babel.c | 2055 +++++++++++++++++++++++++++++++++++++++++ proto/babel/babel.h | 335 +++++++ proto/babel/config.Y | 129 +++ proto/babel/packets.c | 1093 ++++++++++++++++++++++ sysdep/autoconf.h.in | 1 + 19 files changed, 3767 insertions(+), 10 deletions(-) create mode 100644 proto/babel/Doc create mode 100644 proto/babel/Makefile create mode 100644 proto/babel/babel.c create mode 100644 proto/babel/babel.h create mode 100644 proto/babel/config.Y create mode 100644 proto/babel/packets.c diff --git a/configure.in b/configure.in index b9220a1d..16a0b414 100644 --- a/configure.in +++ b/configure.in @@ -206,6 +206,9 @@ fi AC_SUBST(iproutedir) all_protocols="$proto_bfd bgp ospf pipe $proto_radv rip static" +if test "$ip" = ipv6 ; then + all_protocols="$all_protocols babel" +fi all_protocols=`echo $all_protocols | sed 's/ /,/g'` if test "$with_protocols" = all ; then diff --git a/doc/bird.sgml b/doc/bird.sgml index 1a5fbaff..6c6ff3db 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1380,6 +1380,102 @@ corresponding protocol sections. Protocols +Babel + +Introduction + +

The Babel protocol (RFC6126) is a loop-avoiding distance-vector routing +protocol that is robust and efficient both in ordinary wired networks and in +wireless mesh networks. Babel is conceptually very simple in its operation and +"just works" in its default configuration, though some configuration is possible +and in some cases desirable. + +

While the Babel protocol is dual stack (i.e., can carry both IPv4 and IPv6 +routes over the same IPv6 transport), BIRD presently implements only the IPv6 +subset of the protocol. No Babel extensions are implemented, but the BIRD +implementation can coexist with implementations using the extensions (and will +just ignore extension messages). + +

The Babel protocol implementation in BIRD is currently in alpha stage. + +Configuration + +

Babel supports no global configuration options apart from those common to all +other protocols, but supports the following per-interface configuration options: + + +protocol babel [] { + interface { + type ; + rxcost ; + hello interval ; + update interval ; + port ; + tx class|dscp ; + tx priority ; + rx buffer ; + tx length ; + check link ; + }; +} + + + + type wired|wireless + This option specifies the interface type: Wired or wireless. Wired + interfaces are considered more reliable, and so the default hello + interval is higher, and a neighbour is considered unreachable after only + a small number of "hello" packets are lost. On wireless interfaces, + hello packets are sent more often, and the ETX link quality estimation + technique is used to compute the metrics of routes discovered over this + interface. This technique will gradually degrade the metric of routes + when packets are lost rather than the more binary up/down mechanism of + wired type links. Default: rxcost + This specifies the RX cost of the interface. The route metrics will be + computed from this value with a mechanism determined by the interface + hello interval + Interval at which periodic "hello" messages are sent on this interface, + in seconds. Default: 4 seconds. + + update interval + Interval at which periodic (full) updates are sent. Default: 4 times the + hello interval. + + port + This option selects an UDP port to operate on. The default is to operate + on port 6696 as specified in the Babel RFC. + + tx class|dscp|priority + These options specify the ToS/DiffServ/Traffic class/Priority of the + outgoing Babel packets. See common + option for detailed description. + + rx buffer + This option specifies the size of buffers used for packet processing. + The buffer size should be bigger than maximal size of received packets. + The default value is the interface MTU, and the value will be clamped to a + minimum of 512 bytes + IP packet overhead. + + tx length + This option specifies the maximum length of generated Babel packets. To + avoid IP fragmentation, it should not exceed the interface MTU value. + The default value is the interface MTU value, and the value will be + clamped to a minimum of 512 bytes + IP packet overhead. + + check link + If set, the hardware link state (as reported by OS) is taken into + consideration. When the link disappears (e.g. an ethernet cable is + unplugged), neighbors are immediately considered unreachable and all + routes received from them are withdrawn. It is possible that some + hardware drivers or platforms do not implement this feature. Default: + yes. + + +

A nonprivileged user (as an argument to An unprivileged user (as an argument to @@ -1622,7 +1622,7 @@ protocol bfd [<name>] { Default: 5. passive - Generally, both BFD session endpoinds try to establish the session by + Generally, both BFD session endpoints try to establish the session by sending control packets to the other side. This option allows to enable passive mode, which means that the router does not send BFD packets until it has received one from the other side. Default: disabled. @@ -2758,7 +2758,7 @@ protocol ospf <name> { dead num When the router does not receive any messages from a neighbor in secondary switch On BSD systems, older versions of BIRD supported OSPFv2 only for the From 8e433d6a529a883d566dc1d5a4afe0f1e2750baf Mon Sep 17 00:00:00 2001 From: Pavel Tvrdik Date: Thu, 12 May 2016 15:49:44 +0200 Subject: [PATCH 11/13] Prog Doc: Complete several missing parameters --- conf/cf-lex.l | 1 + lib/Doc | 2 +- nest/neighbor.c | 2 +- nest/proto-hooks.c | 1 + nest/proto.c | 1 + nest/rt-attr.c | 2 +- nest/rt-table.c | 9 +++++++-- proto/babel/Doc | 2 +- proto/ospf/dbdes.c | 1 + proto/ospf/lsalib.c | 3 ++- proto/ospf/packet.c | 2 +- sysdep/unix/io.c | 1 + sysdep/unix/log.c | 1 + 13 files changed, 20 insertions(+), 8 deletions(-) diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 5a2a4d6b..727dc017 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -575,6 +575,7 @@ cf_lex_init_kh(void) /** * cf_lex_init - initialize the lexer * @is_cli: true if we're going to parse CLI command, false for configuration + * @c: configuration structure * * cf_lex_init() initializes the lexical analyzer and prepares it for * parsing of a new input. diff --git a/lib/Doc b/lib/Doc index 8f513821..8af1c669 100644 --- a/lib/Doc +++ b/lib/Doc @@ -1,5 +1,5 @@ H Library functions -S ip.c ipv4.c ipv6.c +S ip.c S lists.c S checksum.c bitops.c patmatch.c printf.c xmalloc.c tbf.c D resource.sgml diff --git a/nest/neighbor.c b/nest/neighbor.c index 1685d67e..d974fa51 100644 --- a/nest/neighbor.c +++ b/nest/neighbor.c @@ -339,7 +339,7 @@ neigh_if_link(struct iface *i) /** * neigh_ifa_update: notify neighbor cache about interface address add or remove event - * @ifa: interface address in question + * @a: interface address in question * * Tell the neighbor cache that an address was added or removed. * diff --git a/nest/proto-hooks.c b/nest/proto-hooks.c index e80f87ea..7395b45e 100644 --- a/nest/proto-hooks.c +++ b/nest/proto-hooks.c @@ -148,6 +148,7 @@ void get_route_info(rte *e, byte *buf, ea_list *attrs) * get_attr - get attribute information * @a: an extended attribute * @buf: buffer to be filled with attribute information + * @buflen: a length of the @buf parameter * * The get_attr() hook is called by the core to obtain a user friendly * representation of an extended route attribute. It can either leave diff --git a/nest/proto.c b/nest/proto.c index 3e97e9da..1091b321 100644 --- a/nest/proto.c +++ b/nest/proto.c @@ -718,6 +718,7 @@ graceful_restart_init(void) /** * graceful_restart_done - finalize graceful restart + * @t: unused * * When there are no locks on graceful restart, the functions finalizes the * graceful restart recovery. Protocols postponing route export until the end of diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 7fa05d6d..f181b452 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -405,7 +405,7 @@ ea_find(ea_list *e, unsigned id) * for first occurrences of attributes with ID in specified interval from @id to * (@id + @max - 1), returning pointers to found &eattr structures, storing its * walk state in @s for subsequent calls. - + * * The function ea_walk() is supposed to be called in a loop, with initially * zeroed walk state structure @s with filled the initial extended attribute * list, returning one found attribute in each call or %NULL when no other diff --git a/nest/rt-table.c b/nest/rt-table.c index 57c8b8e0..c02e6dc9 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -717,16 +717,20 @@ rt_notify_merged(struct announce_hook *ah, net *net, rte *new_changed, rte *old_ * @net: network in question * @new: the new route to be announced * @old: the previous route for the same network + * @new_best: the new best route for the same network + * @old_best: the previous best route for the same network + * @before_old: The previous route before @old for the same network. + * If @before_old is NULL @old was the first. * * This function gets a routing table update and announces it * to all protocols that acccepts given type of route announcement * and are connected to the same table by their announcement hooks. * - * Route announcement of type RA_OPTIMAL si generated when optimal + * Route announcement of type %RA_OPTIMAL si generated when optimal * route (in routing table @tab) changes. In that case @old stores the * old optimal route. * - * Route announcement of type RA_ANY si generated when any route (in + * Route announcement of type %RA_ANY si generated when any route (in * routing table @tab) changes In that case @old stores the old route * from the same protocol. * @@ -1616,6 +1620,7 @@ again: /** * rt_prune_table - prune a routing table + * @tab: a routing table for pruning * * This function scans the routing table @tab and removes routes belonging to * flushing protocols, discarded routes and also stale network entries, in a diff --git a/proto/babel/Doc b/proto/babel/Doc index 2480239e..80026f91 100644 --- a/proto/babel/Doc +++ b/proto/babel/Doc @@ -1,2 +1,2 @@ S babel.c -S packet.c +S packets.c diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c index 65bdb3ec..195b03ad 100644 --- a/proto/ospf/dbdes.c +++ b/proto/ospf/dbdes.c @@ -192,6 +192,7 @@ ospf_do_send_dbdes(struct ospf_proto *p, struct ospf_neighbor *n) /** * ospf_send_dbdes - transmit database description packet + * @p: OSPF protocol instance * @n: neighbor * * Sending of a database description packet is described in 10.8 of RFC 2328. diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c index 66a3a23d..1bbd1372 100644 --- a/proto/ospf/lsalib.c +++ b/proto/ospf/lsalib.c @@ -554,12 +554,13 @@ lsa_validate_prefix(struct ospf_lsa_header *lsa, struct ospf_lsa_prefix *body) /** * lsa_validate - check whether given LSA is valid * @lsa: LSA header + * @lsa_type: one of %LSA_T_xxx + * @ospf2: %true means OSPF version 2, %false means OSPF version 3 * @body: pointer to LSA body * * Checks internal structure of given LSA body (minimal length, * consistency). Returns true if valid. */ - int lsa_validate(struct ospf_lsa_header *lsa, u32 lsa_type, int ospf2, void *body) { diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index faa33664..04f0d47c 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -207,7 +207,7 @@ drop: /** * ospf_rx_hook * @sk: socket we received the packet. - * @size: size of the packet + * @len: size of the packet * * This is the entry point for messages from neighbors. Many checks (like * authentication, checksums, size) are done before the packet is passed to diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c index 82f6c69e..486319ff 100644 --- a/sysdep/unix/io.c +++ b/sysdep/unix/io.c @@ -448,6 +448,7 @@ tm_format_reltime(char *x, struct tm *tm, bird_clock_t delta) /** * tm_format_datetime - convert date and time to textual representation * @x: destination buffer of size %TM_DATETIME_BUFFER_SIZE + * @fmt_spec: specification of resulting textual representation of the time * @t: time * * This function formats the given relative time value @t to a textual diff --git a/sysdep/unix/log.c b/sysdep/unix/log.c index b90bbbd2..6665d035 100644 --- a/sysdep/unix/log.c +++ b/sysdep/unix/log.c @@ -89,6 +89,7 @@ static char *class_names[] = { /** * log_commit - commit a log message * @class: message class information (%L_DEBUG to %L_BUG, see |lib/birdlib.h|) + * @buf: message to write * * This function writes a message prepared in the log buffer to the * log file (as specified in the configuration). The log buffer is From 3f2c7600fa2e35b1028c755aa06092b5991e1a8e Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 12 May 2016 21:29:04 +0200 Subject: [PATCH 12/13] We don't need bvsnprintf() in BIRD client --- client/birdc.c | 2 +- client/birdcl.c | 7 ++++--- client/client.c | 29 ++++++++--------------------- client/client.h | 3 +++ client/commands.c | 4 ++-- client/util.c | 7 +++++-- 6 files changed, 23 insertions(+), 29 deletions(-) diff --git a/client/birdc.c b/client/birdc.c index ccf758be..8aa01c17 100644 --- a/client/birdc.c +++ b/client/birdc.c @@ -153,7 +153,7 @@ input_init(void) // readline library does strange things when stdin is nonblocking. // if (fcntl(0, F_SETFL, O_NONBLOCK) < 0) - // die("fcntl: %m"); + // DIE("fcntl"); } static void diff --git a/client/birdcl.c b/client/birdcl.c index 2d5e1067..7b567a9f 100644 --- a/client/birdcl.c +++ b/client/birdcl.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -109,7 +110,7 @@ more_begin(void) tty.c_lflag &= (~ICANON); if (tcsetattr (0, TCSANOW, &tty) < 0) - die("tcsetattr: %m"); + DIE("tcsetattr"); more_active = 1; } @@ -120,7 +121,7 @@ more_end(void) more_active = 0; if (tcsetattr (0, TCSANOW, &stored_tty) < 0) - die("tcsetattr: %m"); + DIE("tcsetattr"); } static void @@ -137,7 +138,7 @@ input_init(void) return; if (tcgetattr(0, &stored_tty) < 0) - die("tcgetattr: %m"); + DIE("tcgetattr"); if (signal(SIGINT, sig_handler) == SIG_IGN) signal(SIGINT, SIG_IGN); diff --git a/client/client.c b/client/client.c index 4075b9e6..0d4bdf3e 100644 --- a/client/client.c +++ b/client/client.c @@ -248,7 +248,7 @@ server_connect(void) server_fd = socket(AF_UNIX, SOCK_STREAM, 0); if (server_fd < 0) - die("Cannot create socket: %m"); + DIE("Cannot create socket"); if (strlen(server_path) >= sizeof(sa.sun_path)) die("server_connect: path too long"); @@ -257,9 +257,9 @@ server_connect(void) sa.sun_family = AF_UNIX; strcpy(sa.sun_path, server_path); if (connect(server_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) < 0) - die("Unable to connect to server control socket (%s): %m", server_path); + DIE("Unable to connect to server control socket (%s)", server_path); if (fcntl(server_fd, F_SETFL, O_NONBLOCK) < 0) - die("fcntl: %m"); + DIE("fcntl"); } @@ -309,13 +309,13 @@ server_read(void) redo: c = read(server_fd, server_read_pos, server_read_buf + sizeof(server_read_buf) - server_read_pos); if (!c) - die("Connection closed by server."); + die("Connection closed by server"); if (c < 0) { if (errno == EINTR) goto redo; else - die("Server read error: %m"); + DIE("Server read error"); } start = server_read_buf; @@ -366,7 +366,7 @@ select_loop(void) if (errno == EINTR) continue; else - die("select: %m"); + DIE("select"); } if (FD_ISSET(0, &select_fds)) @@ -399,7 +399,7 @@ wait_for_write(int fd) if (errno == EINTR) continue; else - die("select: %m"); + DIE("select"); } if (FD_ISSET(server_fd, &set)) @@ -426,7 +426,7 @@ server_send(char *cmd) else if (errno == EINTR) continue; else - die("Server write error: %m"); + DIE("Server write error"); } else { @@ -436,19 +436,6 @@ server_send(char *cmd) } } - -/* XXXX - - get_term_size(); - - if (tcgetattr(0, &tty_save) != 0) - { - perror("tcgetattr error"); - return(EXIT_FAILURE); - } - } - - */ int main(int argc, char **argv) { diff --git a/client/client.h b/client/client.h index b194a772..f9693def 100644 --- a/client/client.h +++ b/client/client.h @@ -34,3 +34,6 @@ char *cmd_expand(char *cmd); /* client.c */ void submit_command(char *cmd_raw); + +/* die() with system error messages */ +#define DIE(x, y...) die(x ": %s", ##y, strerror(errno)) diff --git a/client/commands.c b/client/commands.c index 226ae048..2dae23e1 100644 --- a/client/commands.c +++ b/client/commands.c @@ -60,7 +60,7 @@ cmd_build_tree(void) if (!new) { int size = sizeof(struct cmd_node) + c-d; - new = xmalloc(size); + new = malloc(size); bzero(new, size); *old->plastson = new; old->plastson = &new->sibling; @@ -314,7 +314,7 @@ cmd_expand(char *cmd) puts("No such command. Press `?' for help."); return NULL; } - b = xmalloc(strlen(n->cmd->command) + strlen(args) + 1); + b = malloc(strlen(n->cmd->command) + strlen(args) + 1); sprintf(b, "%s%s", n->cmd->command, args); return b; } diff --git a/client/util.c b/client/util.c index 050224b9..c35cf8f4 100644 --- a/client/util.c +++ b/client/util.c @@ -21,8 +21,11 @@ vlog(const char *msg, va_list args) { char buf[1024]; - if (bvsnprintf(buf, sizeof(buf)-1, msg, args) < 0) - bsprintf(buf + sizeof(buf) - 100, " ... "); + int n = vsnprintf(buf, sizeof(buf), msg, args); + if (n < 0) + snprintf(buf, sizeof(buf), "???"); + if (n >= sizeof(buf)) + snprintf(buf + sizeof(buf) - 100, 100, " ... "); fputs(buf, stderr); fputc('\n', stderr); } From 659f80f262a83d600d5f095fb8a03e912d3fbe64 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 12 May 2016 21:47:29 +0200 Subject: [PATCH 13/13] Make int-new compilable again --- lib/hash.h | 4 ++-- nest/rt-attr.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/hash.h b/lib/hash.h index b86a2eb1..04a16a7e 100644 --- a/lib/hash.h +++ b/lib/hash.h @@ -178,7 +178,7 @@ #define HASH_WALK_FILTER_END } while (0) -typedef mem_hash_t u64; +typedef u64 mem_hash_t; static inline void mem_hash_init(mem_hash_t *h) @@ -199,7 +199,7 @@ mem_hash_mix(mem_hash_t *h, void *p, int s) static inline uint mem_hash_value(mem_hash_t *h) { - return ((value >> 32) ^ (value & 0xffffffff)); + return ((*h >> 32) ^ (*h & 0xffffffff)); } static inline uint diff --git a/nest/rt-attr.c b/nest/rt-attr.c index edd9ebf5..5041ab9f 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -948,7 +948,7 @@ rta_hash(rta *a) { mem_hash_t h; mem_hash_init(&h); -#define MIX(f) mem_hash_mix(&h, &(rta->f), sizeof(rta->f)); +#define MIX(f) mem_hash_mix(&h, &(a->f), sizeof(a->f)); MIX(src); MIX(hostentry); MIX(iface);