diff --git a/nest/bfd.h b/nest/bfd.h index 37561266..d6819fd8 100644 --- a/nest/bfd.h +++ b/nest/bfd.h @@ -21,6 +21,8 @@ struct bfd_options { u8 passive; u8 passive_set; u8 mode; + u8 auth_type; /* Authentication type (BFD_AUTH_*) */ + list *passwords; /* Passwords for authentication */ }; struct bfd_request { diff --git a/nest/config.Y b/nest/config.Y index 594ab3fc..62b28072 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -612,6 +612,8 @@ bfd_item: | MULTIPLIER expr { this_bfd_opts->multiplier = $2; } | PASSIVE bool { this_bfd_opts->passive = $2; this_bfd_opts->passive_set = 1; } | GRACEFUL { this_bfd_opts->mode = BGP_BFD_GRACEFUL; } + | AUTHENTICATION bfd_auth_type { this_bfd_opts->auth_type = $2; } + | password_list {} ; bfd_items: @@ -619,10 +621,34 @@ bfd_items: | bfd_items bfd_item ';' ; +bfd_opts_start: +{ reset_passwords(); } ; + +bfd_opts_end: +{ + this_bfd_opts->passwords = get_passwords(); + + if (!this_bfd_opts->auth_type != !this_bfd_opts->passwords) + cf_warn("Authentication and password options should be used together"); + + if (this_bfd_opts->passwords) + { + struct password_item *pass; + WALK_LIST(pass, *this_bfd_opts->passwords) + { + if (pass->alg) + cf_error("Password algorithm option not available in BFD protocol"); + + pass->alg = bfd_auth_type_to_hash_alg[this_bfd_opts->auth_type]; + } + } +}; + bfd_opts: - '{' bfd_items '}' + bfd_opts_start '{' bfd_items '}' bfd_opts_end ; + /* Core commands */ CF_CLI_HELP(SHOW, ..., [[Show status information]]) diff --git a/proto/bfd/bfd.c b/proto/bfd/bfd.c index 41d8e210..4f8499ba 100644 --- a/proto/bfd/bfd.c +++ b/proto/bfd/bfd.c @@ -174,6 +174,8 @@ bfd_merge_options(const struct bfd_iface_config *cf, const struct bfd_options *o .idle_tx_int = opts->idle_tx_int ?: cf->idle_tx_int, .multiplier = opts->multiplier ?: cf->multiplier, .passive = opts->passive_set ? opts->passive : cf->passive, + .auth_type = opts->auth_type ?: cf->auth_type, + .passwords = opts->passwords ?: cf->passwords, }; } @@ -1195,7 +1197,7 @@ bfd_show_session(struct bfd_session *s, int details) const char *ifname = (s->ifa && s->ifa->iface) ? s->ifa->iface->name : "---"; btime tx_int = s->last_tx ? MAX(s->des_min_tx_int, s->rem_min_rx_int) : 0; btime timeout = (btime) MAX(s->req_min_rx_int, s->rem_min_tx_int) * s->rem_detect_mult; - u8 auth_type = s->ifa->cf->auth_type; + u8 auth_type = s->cf.auth_type; loc_state = (loc_state < 4) ? loc_state : 0; rem_state = (rem_state < 4) ? rem_state : 0; diff --git a/proto/bfd/bfd.h b/proto/bfd/bfd.h index e711bc80..847c6b14 100644 --- a/proto/bfd/bfd.h +++ b/proto/bfd/bfd.h @@ -69,6 +69,8 @@ struct bfd_session_config u32 idle_tx_int; u8 multiplier; u8 passive; + u8 auth_type; /* Authentication type (BFD_AUTH_*) */ + list *passwords; /* Passwords for authentication */ }; struct bfd_neighbor diff --git a/proto/bfd/packets.c b/proto/bfd/packets.c index e2ec5988..aec91ca6 100644 --- a/proto/bfd/packets.c +++ b/proto/bfd/packets.c @@ -109,7 +109,7 @@ const u8 bfd_auth_type_to_hash_alg[] = { static void bfd_fill_authentication(struct bfd_proto *p, struct bfd_session *s, struct bfd_ctl_packet *pkt) { - struct bfd_iface_config *cf = s->ifa->cf; + struct bfd_session_config *cf = &s->cf; struct password_item *pass = password_find(cf->passwords, 0); uint meticulous = 0; @@ -179,7 +179,7 @@ bfd_fill_authentication(struct bfd_proto *p, struct bfd_session *s, struct bfd_c static int bfd_check_authentication(struct bfd_proto *p, struct bfd_session *s, struct bfd_ctl_packet *pkt) { - struct bfd_iface_config *cf = s->ifa->cf; + struct bfd_session_config *cf = &s->cf; const char *err_dsc = NULL; uint err_val = 0; uint auth_type = 0; @@ -306,7 +306,7 @@ bfd_send_ctl(struct bfd_proto *p, struct bfd_session *s, int final) else if (s->poll_active) pkt->flags |= BFD_FLAG_POLL; - if (s->ifa->cf->auth_type) + if (s->cf.auth_type) bfd_fill_authentication(p, s, pkt); if (sk->tbuf != sk->tpos)