diff options
Diffstat (limited to 'proto/bfd/config.Y')
-rw-r--r-- | proto/bfd/config.Y | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/proto/bfd/config.Y b/proto/bfd/config.Y new file mode 100644 index 00000000..1bf8764f --- /dev/null +++ b/proto/bfd/config.Y @@ -0,0 +1,138 @@ +/* + * BIRD -- Router Advertisement Configuration + * + * + * Can be freely distributed and used under the terms of the GNU GPL. + */ + +CF_HDR + +#include "proto/bfd/bfd.h" + +CF_DEFINES + +#define BFD_CFG ((struct bfd_config *) this_proto) +#define BFD_IFACE ((struct bfd_iface_config *) this_ipatt) +#define BFD_NEIGHBOR this_bfd_neighbor + +static struct bfd_neighbor *this_bfd_neighbor; + +extern struct bfd_config *bfd_cf; + +CF_DECLS + +CF_KEYWORDS(BFD, MIN, IDLE, RX, TX, INTERVAL, MULTIPLIER, PASSIVE, + INTERFACE, MULTIHOP, NEIGHBOR, DEV, LOCAL) + +%type <iface> bfd_neigh_iface +%type <a> bfd_neigh_local +%type <i> bfd_neigh_multihop + +CF_GRAMMAR + +CF_ADDTO(proto, bfd_proto) + +bfd_proto_start: proto_start BFD +{ + this_proto = proto_config_new(&proto_bfd, sizeof(struct bfd_config), $1); + init_list(&BFD_CFG->patt_list); + init_list(&BFD_CFG->neigh_list); + + if (bfd_cf) + cf_error("Only one BFD instance allowed"); + bfd_cf = BFD_CFG; +}; + +bfd_proto_item: + proto_item + | INTERFACE bfd_iface + | MULTIHOP bfd_multihop + | NEIGHBOR bfd_neighbor + ; + +bfd_proto_opts: + /* empty */ + | bfd_proto_opts bfd_proto_item ';' + ; + +bfd_proto: + bfd_proto_start proto_name '{' bfd_proto_opts '}'; + + +bfd_iface_start: +{ + this_ipatt = cfg_allocz(sizeof(struct bfd_iface_config)); + init_list(&this_ipatt->ipn_list); + + BFD_IFACE->min_rx_int = BFD_DEFAULT_MIN_RX_INT; + BFD_IFACE->min_tx_int = BFD_DEFAULT_MIN_TX_INT; + BFD_IFACE->idle_tx_int = BFD_DEFAULT_IDLE_TX_INT; + BFD_IFACE->multiplier = BFD_DEFAULT_MULTIPLIER; +}; + +bfd_iface_item: + INTERVAL expr_us { BFD_IFACE->min_rx_int = BFD_IFACE->min_tx_int = $2; } + | MIN RX INTERVAL expr_us { BFD_IFACE->min_rx_int = $4; } + | MIN TX INTERVAL expr_us { BFD_IFACE->min_tx_int = $4; } + | IDLE TX INTERVAL expr_us { BFD_IFACE->idle_tx_int = $4; } + | MULTIPLIER expr { BFD_IFACE->multiplier = $2; } + | PASSIVE bool { BFD_IFACE->passive = $2; } + ; + +bfd_iface_opts: + /* empty */ + | bfd_iface_opts bfd_iface_item ';' + ; + +bfd_iface_opt_list: + /* empty */ + | '{' bfd_iface_opts '}' + ; + +bfd_iface: bfd_iface_start iface_patt_list bfd_iface_opt_list +{ add_tail(&BFD_CFG->patt_list, NODE this_ipatt); }; + +bfd_multihop: bfd_iface_start bfd_iface_opt_list +{ BFD_CFG->multihop = BFD_IFACE; }; + + +bfd_neigh_iface: + /* empty */ { $$ = NULL; } + | '%' SYM { $$ = if_get_by_name($2->name); } + | DEV TEXT { $$ = if_get_by_name($2); } + ; + +bfd_neigh_local: + /* empty */ { $$ = IPA_NONE; } + | LOCAL ipa { $$ = $2; } + ; + +bfd_neigh_multihop: + /* empty */ { $$ = 0; } + | MULTIHOP bool { $$ = $2; } + ; + +bfd_neighbor: ipa bfd_neigh_iface bfd_neigh_local bfd_neigh_multihop +{ + this_bfd_neighbor = cfg_allocz(sizeof(struct bfd_neighbor)); + add_tail(&BFD_CFG->neigh_list, NODE this_bfd_neighbor); + + BFD_NEIGHBOR->addr = $1; + BFD_NEIGHBOR->local = $3; + BFD_NEIGHBOR->iface = $2; + BFD_NEIGHBOR->multihop = $4; + + if ($4 && $2) + cf_error("Neighbor cannot set both interface and multihop"); + + if ($4 && ipa_zero($3)) + cf_error("Multihop neighbor requires specified local address"); +}; + + +CF_CLI(SHOW BFD SESSIONS, optsym, [<name>], [[Show information about BFD sessions]]) +{ bfd_show_sessions(proto_get_named($4, &proto_bfd)); }; + +CF_CODE + +CF_END |