From 36da2857bc911924a250a234f38cf58c3b21f1bc Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Fri, 8 Feb 2013 23:58:27 +0100 Subject: Implements router advertisements activated by received routes. The RAdv protocol could be configured to change its behavior based on availability of routes, e.g., do not announce router lifetime when a default route is not available. --- proto/radv/radv.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 2 deletions(-) (limited to 'proto/radv/radv.c') diff --git a/proto/radv/radv.c b/proto/radv/radv.c index 5e7296a3..a6b9b16c 100644 --- a/proto/radv/radv.c +++ b/proto/radv/radv.c @@ -30,6 +30,13 @@ * by RA_EV_* codes), and radv_timer(), which triggers sending RAs and * computes the next timeout. * + * The RAdv protocol could receive routes (through + * radv_import_control() and radv_rt_notify()), but only the + * configured trigger route is tracked (in &active var). When a radv + * protocol is reconfigured, the connected routing table is examined + * (in radv_check_active()) to have proper &active value in case of + * the specified trigger prefix was changed. + * * Supported standards: * - RFC 4861 - main RA standard * - RFC 6106 - DNS extensions (RDDNS, DNSSL) @@ -93,6 +100,16 @@ radv_iface_notify(struct radv_iface *ifa, int event) tm_start(ifa->timer, after); } +static void +radv_iface_notify_all(struct proto_radv *ra, int event) +{ + struct radv_iface *ifa; + + WALK_LIST(ifa, ra->iface_list) + radv_iface_notify(ifa, event); +} + + static struct radv_iface * radv_iface_find(struct proto_radv *ra, struct iface *what) { @@ -238,11 +255,68 @@ radv_ifa_notify(struct proto *p, unsigned flags, struct ifa *a) radv_iface_notify(ifa, RA_EV_CHANGE); } +static inline int radv_net_match_trigger(struct radv_config *cf, net *n) +{ + return cf->trigger_valid && + (n->n.pxlen == cf->trigger_pxlen) && + ipa_equal(n->n.prefix, cf->trigger_prefix); +} + +int +radv_import_control(struct proto *p, rte **new, ea_list **attrs UNUSED, struct linpool *pool UNUSED) +{ + // struct proto_radv *ra = (struct proto_radv *) p; + struct radv_config *cf = (struct radv_config *) (p->cf); + + if (radv_net_match_trigger(cf, (*new)->net)) + return RIC_PROCESS; + + return RIC_DROP; +} + +static void +radv_rt_notify(struct proto *p, rtable *tbl UNUSED, net *n, rte *new, rte *old UNUSED, ea_list *attrs UNUSED) +{ + struct proto_radv *ra = (struct proto_radv *) p; + struct radv_config *cf = (struct radv_config *) (p->cf); + + if (radv_net_match_trigger(cf, n)) + { + u8 old_active = ra->active; + ra->active = !!new; + + if (ra->active == old_active) + return; + + if (ra->active) + RADV_TRACE(D_EVENTS, "Triggered"); + else + RADV_TRACE(D_EVENTS, "Suppressed"); + + radv_iface_notify_all(ra, RA_EV_CHANGE); + } +} + +static int +radv_check_active(struct proto_radv *ra) +{ + struct radv_config *cf = (struct radv_config *) (ra->p.cf); + + if (! cf->trigger_valid) + return 1; + + return rt_examine(ra->p.table, cf->trigger_prefix, cf->trigger_pxlen, + &(ra->p), ra->p.cf->out_filter); +} + static struct proto * radv_init(struct proto_config *c) { struct proto *p = proto_new(c, sizeof(struct proto_radv)); + p->accept_ra_types = RA_OPTIMAL; + p->import_control = radv_import_control; + p->rt_notify = radv_rt_notify; p->if_notify = radv_if_notify; p->ifa_notify = radv_ifa_notify; return p; @@ -252,9 +326,10 @@ static int radv_start(struct proto *p) { struct proto_radv *ra = (struct proto_radv *) p; - // struct radv_config *cf = (struct radv_config *) (p->cf); + struct radv_config *cf = (struct radv_config *) (p->cf); init_list(&(ra->iface_list)); + ra->active = !cf->trigger_valid; return PS_UP; } @@ -293,6 +368,9 @@ radv_reconfigure(struct proto *p, struct proto_config *c) * causing nodes to temporary remove their default routes. */ + p->cf = c; /* radv_check_active() requires proper p->cf */ + ra->active = radv_check_active(ra); + struct iface *iface; WALK_LIST(iface, iface_list) { @@ -335,6 +413,14 @@ radv_copy_config(struct proto_config *dest, struct proto_config *src) cfg_copy_list(&d->pref_list, &s->pref_list, sizeof(struct radv_prefix_config)); } +static void +radv_get_status(struct proto *p, byte *buf) +{ + struct proto_radv *ra = (struct proto_radv *) p; + + if (!ra->active) + strcpy(buf, "Suppressed"); +} struct protocol proto_radv = { .name = "RAdv", @@ -343,5 +429,6 @@ struct protocol proto_radv = { .start = radv_start, .shutdown = radv_shutdown, .reconfigure = radv_reconfigure, - .copy_config = radv_copy_config + .copy_config = radv_copy_config, + .get_status = radv_get_status }; -- cgit v1.2.3 From 1ec522538fb81a56b068c087d0a842faf7aa7869 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Tue, 19 Nov 2013 22:33:48 +0100 Subject: BFD protocol, ready for release. Supports OSPF and BGP and also statically configured sessions. --- aclocal.m4 | 12 + configure.in | 35 ++- doc/bird.sgml | 195 +++++++++++++- lib/birdlib.h | 2 + lib/printf.c | 2 +- nest/proto.c | 7 +- proto/bfd/bfd.c | 685 ++++++++++++++++++++++++++++++++++++++++---------- proto/bfd/bfd.h | 42 ++-- proto/bfd/config.Y | 82 +++--- proto/bfd/io.c | 36 ++- proto/bfd/io.h | 11 +- proto/bfd/packets.c | 37 +-- proto/bgp/bgp.c | 48 +++- proto/bgp/bgp.h | 5 + proto/bgp/config.Y | 3 +- proto/ospf/config.Y | 1 + proto/ospf/hello.c | 3 + proto/ospf/iface.c | 14 ++ proto/ospf/neighbor.c | 30 +++ proto/ospf/neighbor.h | 1 + proto/ospf/ospf.h | 4 + proto/radv/radv.c | 2 +- sysdep/autoconf.h.in | 4 + sysdep/unix/io.c | 2 + sysdep/unix/log.c | 9 +- 25 files changed, 1044 insertions(+), 228 deletions(-) (limited to 'proto/radv/radv.c') diff --git a/aclocal.m4 b/aclocal.m4 index 3ceb6eb6..02c0f76b 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -133,6 +133,18 @@ if test "$bird_cv_struct_ip_mreqn" = yes ; then fi ]) +AC_DEFUN(BIRD_CHECK_PTHREADS, +[ + bird_tmp_cflags="$CFLAGS" + + CFLAGS="$CFLAGS -pthread" + AC_CACHE_CHECK([whether POSIX threads are available], bird_cv_lib_pthreads, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[pthread_t pt; pthread_create(&pt, NULL, NULL, NULL); pthread_spinlock_t lock; pthread_spin_lock(&lock); ]])], + [bird_cv_lib_pthreads=yes], [bird_cv_lib_pthreads=no])]) + + CFLAGS="$bird_tmp_cflags" +]) + AC_DEFUN(BIRD_CHECK_GCC_OPTION, [ bird_tmp_cflags="$CFLAGS" diff --git a/configure.in b/configure.in index fc18657d..9b5dc3e2 100644 --- a/configure.in +++ b/configure.in @@ -10,6 +10,7 @@ AC_ARG_ENABLE(debug, [ --enable-debug enable internal debugging routin AC_ARG_ENABLE(memcheck, [ --enable-memcheck check memory allocations when debugging (default: enabled)],,enable_memcheck=yes) AC_ARG_ENABLE(client, [ --enable-client enable building of BIRD client (default: enabled)],,enable_client=yes) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 enable building of IPv6 version (default: disabled)],,enable_ipv6=no) +AC_ARG_ENABLE(pthreads, [ --enable-pthreads enable POSIX threads support (default: detect)],,enable_pthreads=try) AC_ARG_WITH(suffix, [ --with-suffix=STRING use specified suffix for BIRD files (default: 6 for IPv6 version)],[given_suffix="yes"]) AC_ARG_WITH(sysconfig, [ --with-sysconfig=FILE use specified BIRD system configuration file]) AC_ARG_WITH(protocols, [ --with-protocols=LIST include specified routing protocols (default: all)],,[with_protocols="all"]) @@ -47,11 +48,10 @@ AC_SUBST(runtimedir) if test "$enable_ipv6" = yes ; then ip=ipv6 SUFFIX=6 - all_protocols=bfd,bgp,ospf,pipe,radv,rip,static + proto_radv=radv else ip=ipv4 SUFFIX="" - all_protocols=bfd,bgp,ospf,pipe,rip,static fi if test "$given_suffix" = yes ; then @@ -59,10 +59,6 @@ if test "$given_suffix" = yes ; then fi AC_SUBST(SUFFIX) -if test "$with_protocols" = all ; then - with_protocols="$all_protocols" -fi - if test "$enable_debug" = yes ; then CONFIG_FILE="bird$SUFFIX.conf" CONTROL_SOCKET="bird$SUFFIX.ctl" @@ -87,12 +83,29 @@ if test -z "$GCC" ; then AC_MSG_ERROR([This program requires the GNU C Compiler.]) fi +if test "$enable_pthreads" != no ; then + BIRD_CHECK_PTHREADS + + if test "$bird_cv_lib_pthreads" = yes ; then + AC_DEFINE(USE_PTHREADS) + CFLAGS="$CFLAGS -pthread" + LDFLAGS="$LDFLAGS -pthread" + proto_bfd=bfd + elif test "$enable_pthreads" = yes ; then + AC_MSG_ERROR([POSIX threads not available.]) + fi + + if test "$enable_pthreads" = try ; then + enable_pthreads="$bird_cv_lib_pthreads" + fi +fi + if test "$bird_cflags_default" = yes ; then BIRD_CHECK_GCC_OPTION(bird_cv_c_option_wno_pointer_sign, -Wno-pointer-sign, -Wall) BIRD_CHECK_GCC_OPTION(bird_cv_c_option_fno_strict_aliasing, -fno-strict-aliasing) BIRD_CHECK_GCC_OPTION(bird_cv_c_option_fno_strict_overflow, -fno-strict-overflow) - CFLAGS="$CFLAGS -pthread -Wall -Wstrict-prototypes -Wno-parentheses" + CFLAGS="$CFLAGS -Wall -Wstrict-prototypes -Wno-parentheses" BIRD_ADD_GCC_OPTION(bird_cv_c_option_wno_pointer_sign, -Wno-pointer-sign) BIRD_ADD_GCC_OPTION(bird_cv_c_option_fno_strict_aliasing, -fno-strict-aliasing) BIRD_ADD_GCC_OPTION(bird_cv_c_option_fno_strict_overflow, -fno-strict-overflow) @@ -183,6 +196,13 @@ fi AC_SUBST(iproutedir) +all_protocols="$proto_bfd bgp ospf pipe $proto_radv rip static" +all_protocols=`echo $all_protocols | sed 's/ /,/g'` + +if test "$with_protocols" = all ; then + with_protocols="$all_protocols" +fi + AC_MSG_CHECKING([protocols]) protocols=`echo "$with_protocols" | sed 's/,/ /g'` if test "$protocols" = no ; then protocols= ; fi @@ -272,6 +292,7 @@ BIRD was configured with the following options: Iproute2 directory: $iproutedir System configuration: $sysdesc Debugging: $enable_debug + POSIX threads: $enable_pthreads Routing protocols: $protocols Client: $enable_client EOF diff --git a/doc/bird.sgml b/doc/bird.sgml index 3cd80c32..3bc0e453 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1244,6 +1244,178 @@ undefined value is regarded as empty clist for most purposes. Protocols +