diff --git a/NEWS b/NEWS index 4e3349c3..614cc7e4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,14 @@ +Version 1.4.2 (2014-04-02) + o Important bugfix in BFD. + +Version 1.4.1 (2014-03-31) + o BGP add-path support (RFC draft). + o BGP graceful restart (RFC 4724). + o OSPF: many changes in socket layer. + o OSPF: support for secondary addresses in BSD. + o OSPF: names for vlink pseudointerfaces (vlinkX). + o Several bugfixes. + Version 1.4.0 (2013-11-25) o BFD protocol (RFC 5880). o BFD support for OSPF and BGP. diff --git a/client/birdc.c b/client/birdc.c index bbe18331..6d4c86a9 100644 --- a/client/birdc.c +++ b/client/birdc.c @@ -29,7 +29,6 @@ static int prompt_active; /* HACK: libreadline internals we need to access */ extern int _rl_vis_botlin; extern void _rl_move_vert(int); -extern Function *rl_last_func; static void add_history_dedup(char *cmd) diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 217e02e6..1f281bdc 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -265,9 +265,6 @@ cf_hash(byte *c) * match - these do not have fd and flex buffer yet). * * FIXME: Most of these ifs and include functions are really sysdep/unix. - * - * FIXME: Resources (fd, flex buffers and glob data) in IFS stack - * are not freed when cf_error() is called. */ static struct include_file_stack * @@ -306,13 +303,36 @@ enter_ifs(struct include_file_stack *new) yy_switch_to_buffer(new->buffer); } +/** + * cf_lex_unwind - unwind lexer state during error + * + * cf_lex_unwind() frees the internal state on IFS stack when the lexical + * analyzer is terminated by cf_error(). + */ +void +cf_lex_unwind(void) +{ + struct include_file_stack *n; + + for (n = ifs; n != ifs_head; n = n->prev) + { + /* Memory is freed automatically */ + if (n->buffer) + yy_delete_buffer(n->buffer); + if (n->fd) + close(n->fd); + } + + ifs = ifs_head; +} + static void cf_include(char *arg, int alen) { struct include_file_stack *base_ifs = ifs; int new_depth, rv, i; char *patt; - glob_t g; + glob_t g = {}; new_depth = ifs->depth + 1; if (new_depth > MAX_INCLUDE_DEPTH) @@ -360,7 +380,10 @@ cf_include(char *arg, int alen) struct stat fs; if (stat(fname, &fs) < 0) - cf_error("Unable to stat included file %s: %m", fname); + { + globfree(&g); + cf_error("Unable to stat included file %s: %m", fname); + } if (fs.st_mode & S_IFDIR) continue; diff --git a/conf/conf.c b/conf/conf.c index a327106d..0d54436e 100644 --- a/conf/conf.c +++ b/conf/conf.c @@ -503,6 +503,7 @@ cf_error(char *msg, ...) new_config->err_msg = cfg_strdup(buf); new_config->err_lino = ifs->lino; new_config->err_file_name = ifs->file_name; + cf_lex_unwind(); longjmp(conf_jmpbuf, 1); } diff --git a/conf/conf.h b/conf/conf.h index a8bba7e8..fa14d7b5 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -139,6 +139,8 @@ extern struct include_file_stack *ifs; int cf_lex(void); void cf_lex_init(int is_cli, struct config *c); +void cf_lex_unwind(void); + struct symbol *cf_find_symbol(byte *c); struct symbol *cf_default_name(char *template, int *counter); struct symbol *cf_define_symbol(struct symbol *symbol, int type, void *def); diff --git a/doc/bird.sgml b/doc/bird.sgml index a7f70df5..07e75588 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -160,7 +160,7 @@ BIRD executable by configuring out routing protocols you don't use, and default is /var/run/bird.ctl. -P - create a PID file with given filename. + create a PID file with given filename. -u drop privileges and use that user ID, see the next section for details. @@ -393,7 +393,7 @@ protocol rip { Set BIRD's router ID based on an IP address of an interface specified by an interface pattern. The option is applicable for IPv4 version only. See section for detailed - description of interface patterns. + description of interface patterns with extended clauses. listen bgp [address This option allows to specify address and port where BGP protocol should @@ -569,23 +569,26 @@ agreement"). given interface-specific options. A set of interfaces specified by one interface option is described using an interface pattern. The interface pattern consists of a sequence of clauses (separated by commas), each - clause may contain a mask, a prefix, or both of them. An interface - matches the clause if its name matches the mask (if specified) and its - address matches the prefix (if specified). Mask is specified as - shell-like pattern. For IPv6, the prefix part of a clause is generally - ignored and interfaces are matched just by their name. + clause is a mask specified as a shell-like pattern. Interfaces are + matched by their name. An interface matches the pattern if it matches any of its clauses. If the clause begins with . development, expect some rough edges and possible UI and configuration changes in the future. Also note that we currently support at most one protocol instance. +

BFD packets are sent with a dynamic source port number. Linux systems use by +default a bit different dynamic port range than the IANA approved one +(49152-65535). If you experience problems with compatibility, please adjust +/proc/sys/net/ipv4/ip_local_port_range + Configuration

BFD configuration consists mainly of multiple definitions of interfaces. @@ -2094,9 +2102,11 @@ on Linux systems BIRD cannot change non-BIRD route in the kernel routing table. interface By default, the Direct protocol will generate device routes for all the interfaces available. If you want to restrict it to some subset of - interfaces (for example if you're using multiple routing tables for - policy routing and some of the policy domains don't contain all - interfaces), just use this clause. + interfaces or addresses (e.g. if you're using multiple routing tables + for policy routing and some of the policy domains don't contain all + interfaces), just use this clause. See + common option for detailed description. The Direct protocol uses + extended interface clauses.

Direct device routes don't contain any specific attributes. @@ -2468,9 +2478,11 @@ protocol ospf <name> { interface pattern [instance Defines that the specified interfaces belong to the area being defined. See common option for detailed - description. In OSPFv3, you can specify instance ID for that interface - description, so it is possible to have several instances of that - interface with different options or even in different areas. + description. In OSPFv2, extended interface clauses are used, because + OSPFv2 handles each network prefix as a separate virtual interface. In + OSPFv3, you can specify instance ID for that interface description, so + it is possible to have several instances of that interface with + different options or even in different areas. virtual link id [instance Virtual link to router with the router id. Virtual link acts as a @@ -2683,7 +2695,7 @@ network. This attribute is read-only. Default is Example - +

protocol ospf MyOSPF { rfc1583compat yes; tick 2; diff --git a/misc/bird.spec b/misc/bird.spec index 162dac55..69f2dc78 100644 --- a/misc/bird.spec +++ b/misc/bird.spec @@ -1,6 +1,6 @@ Summary: BIRD Internet Routing Daemon Name: bird -Version: 1.4.0 +Version: 1.4.2 Release: 1 Copyright: GPL Group: Networking/Daemons diff --git a/nest/config.Y b/nest/config.Y index c8ebd9bc..e9c00e02 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -24,6 +24,17 @@ static list *this_p_list; static struct password_item *this_p_item; static int password_id; +static void +iface_patt_check(void) +{ + struct iface_patt_node *pn; + + WALK_LIST(pn, this_ipatt->ipn_list) + if (!pn->pattern || pn->pxlen) + cf_error("Interface name/mask expected, not IP prefix"); +} + + static inline void reset_passwords(void) { @@ -279,6 +290,9 @@ iface_patt_list: | iface_patt_list ',' iface_patt_node ; +/* For name/mask-only iface patterns */ +iface_patt_list_nopx: iface_patt_list { iface_patt_check(); } + iface_patt_init: { /* Generic this_ipatt init */ this_ipatt = cfg_allocz(sizeof(struct iface_patt)); diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 315d132b..7bbe8c21 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -477,8 +477,15 @@ bfd_remove_session(struct bfd_proto *p, struct bfd_session *s) { ip_addr ip = s->addr; + /* Caller should ensure that request list is empty */ + birdloop_enter(p->loop); + /* Remove session from notify list if scheduled for notification */ + /* No need for bfd_lock_sessions(), we are already protected by birdloop_enter() */ + if (NODE_VALID(&s->n)) + rem_node(&s->n); + bfd_free_iface(s->ifa); rfree(s->tx_timer); diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y index 1bf8764f..948079df 100644 --- a/proto/bfd/config.Y +++ b/proto/bfd/config.Y @@ -89,7 +89,7 @@ bfd_iface_opt_list: | '{' bfd_iface_opts '}' ; -bfd_iface: bfd_iface_start iface_patt_list bfd_iface_opt_list +bfd_iface: bfd_iface_start iface_patt_list_nopx bfd_iface_opt_list { add_tail(&BFD_CFG->patt_list, NODE this_ipatt); }; bfd_multihop: bfd_iface_start bfd_iface_opt_list @@ -130,6 +130,7 @@ bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop }; +CF_CLI_HELP(SHOW BFD, ..., [[Show information about BFD protocol]]); CF_CLI(SHOW BFD SESSIONS, optsym, [], [[Show information about BFD sessions]]) { bfd_show_sessions(proto_get_named($4, &proto_bfd)); }; diff --git a/proto/bgp/packets.c b/proto/bgp/packets.c index 620f7172..5636acb3 100644 --- a/proto/bgp/packets.c +++ b/proto/bgp/packets.c @@ -1201,7 +1201,7 @@ bgp_do_rx_update(struct bgp_conn *conn, return; /* Check for End-of-RIB marker */ - if ((attr_len < 8) && !withdrawn_len && !attr_len && + if ((attr_len < 8) && !withdrawn_len && !nlri_len && !p->mp_reach_len && (p->mp_unreach_len == 3) && (get_u16(p->mp_unreach_start) == BGP_AF_IPV6)) { bgp_rx_end_mark(p); diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 40b14c4f..99031c0b 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -379,6 +379,10 @@ ospf_instance_id: } ; +ospf_iface_patt_list: + iface_patt_list { if (OSPF_VERSION == 3) iface_patt_check(); } ospf_instance_id + ; + ospf_iface_opts: /* empty */ | ospf_iface_opts ospf_iface_item ';' @@ -390,7 +394,7 @@ ospf_iface_opt_list: ; ospf_iface: - ospf_iface_start iface_patt_list ospf_instance_id ospf_iface_opt_list { ospf_iface_finish(); } + ospf_iface_start ospf_iface_patt_list ospf_iface_opt_list { ospf_iface_finish(); } ; opttext: diff --git a/proto/radv/config.Y b/proto/radv/config.Y index ff70a2f7..88a9e298 100644 --- a/proto/radv/config.Y +++ b/proto/radv/config.Y @@ -138,7 +138,7 @@ radv_iface_opt_list: ; radv_iface: - radv_iface_start iface_patt_list radv_iface_opt_list radv_iface_finish; + radv_iface_start iface_patt_list_nopx radv_iface_opt_list radv_iface_finish; radv_prefix_start: prefix diff --git a/proto/rip/config.Y b/proto/rip/config.Y index 57e291cb..49890364 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -116,7 +116,7 @@ rip_iface_init: } ; -rip_iface: +rip_iface: /* TODO: switch to iface_patt_list_nopx */ rip_iface_init iface_patt_list rip_iface_opt_list ; diff --git a/sysdep/config.h b/sysdep/config.h index 2b668d0c..a32f6cfa 100644 --- a/sysdep/config.h +++ b/sysdep/config.h @@ -7,7 +7,7 @@ #define _BIRD_CONFIG_H_ /* BIRD version */ -#define BIRD_VERSION "1.4.0" +#define BIRD_VERSION "1.4.2" // XXXX temporary define #define IPV1 1 diff --git a/sysdep/linux/sysio.h b/sysdep/linux/sysio.h index 433f3a9a..ed7504bf 100644 --- a/sysdep/linux/sysio.h +++ b/sysdep/linux/sysio.h @@ -87,6 +87,8 @@ sk_leave_group4(sock *s, ip_addr maddr) #define TCP_MD5SIG 14 #define TCP_MD5SIG_MAXKEYLEN 80 +#include + struct tcp_md5sig { struct sockaddr_storage tcpm_addr; /* address associated */ __u16 __tcpm_pad1; /* zero */