From f2ae2badff37c008ba8217a12f8ee6dc6a3c5a39 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 7 Apr 2016 12:20:45 +0200 Subject: Main: Add local option Add option that changes default paths for config file and control socket to the current working directory. --- doc/bird.sgml | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'doc/bird.sgml') 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. -- cgit v1.2.3 From e90dd656cc9126e1fbcc45fb77a10bf1baa2a1b5 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Fri, 8 Apr 2016 15:10:57 +0200 Subject: 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(-) (limited to 'doc/bird.sgml') 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 -- cgit v1.2.3 From 43fc6bb0fb720762f12124076e2241855741ceb5 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Mon, 11 Apr 2016 00:41:10 +0200 Subject: Documentation update --- doc/bird.sgml | 98 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 22 deletions(-) (limited to 'doc/bird.sgml') 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 + } } -- cgit v1.2.3 From a7baa09862e6b4856cd66197c6bd74c7df336b8f Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Wed, 13 Apr 2016 14:30:28 +0200 Subject: 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 (limited to 'doc/bird.sgml') 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) -- cgit v1.2.3 From 937e75d8f1d203b637ba0ea050026f9af92485f3 Mon Sep 17 00:00:00 2001 From: "Ondrej Zajicek (work)" Date: Thu, 28 Apr 2016 18:01:40 +0200 Subject: 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 (limited to 'doc/bird.sgml') 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 -- cgit v1.2.3