#include "lib/libfrr.h"
#include "lib/qobj.h"
#include "lib/queue.h"
+#include "lib/vrf.h"
#include "bfdctl.h"
-#define ETHERNET_ADDRESS_LENGTH 6
-
#ifdef BFD_DEBUG
#define BFDD_JSON_CONV_OPTIONS (JSON_C_TO_STRING_PRETTY)
#else
DECLARE_MTYPE(BFDD_CONFIG);
DECLARE_MTYPE(BFDD_LABEL);
DECLARE_MTYPE(BFDD_CONTROL);
+DECLARE_MTYPE(BFDD_SESSION_OBSERVER);
DECLARE_MTYPE(BFDD_NOTIFICATION);
struct bfd_timers {
* expires
*/
BFD_SESS_FLAG_SHUTDOWN = 1 << 7, /* disable BGP peer function */
+ BFD_SESS_FLAG_CONFIG = 1 << 8, /* Session configured with bfd NB API */
};
#define BFD_SET_FLAG(field, flag) (field |= flag)
#define BFD_CHECK_FLAG(field, flag) (field & flag)
/* BFD session hash keys */
-struct bfd_shop_key {
- struct sockaddr_any peer;
- char port_name[MAXNAMELEN + 1];
-};
-
-struct bfd_mhop_key {
- struct sockaddr_any peer;
- struct sockaddr_any local;
- char vrf_name[MAXNAMELEN + 1];
+struct bfd_key {
+ uint16_t family;
+ uint8_t mhop;
+ struct in6_addr peer;
+ struct in6_addr local;
+ char ifname[MAXNAMELEN];
+ char vrfname[MAXNAMELEN];
};
struct bfd_session_stats {
/* Timers */
struct bfd_timers timers;
- struct bfd_timers new_timers;
- uint32_t up_min_tx;
+ struct bfd_timers cur_timers;
uint64_t detect_TO;
struct thread *echo_recvtimer_ev;
struct thread *recvtimer_ev;
uint8_t polling;
/* This and the localDiscr are the keys to state info */
+ struct bfd_key key;
struct peer_label *pl;
- union {
- struct bfd_shop_key shop;
- struct bfd_mhop_key mhop;
- };
- int sock;
struct sockaddr_any local_address;
- struct sockaddr_any local_ip;
- int ifindex;
- uint8_t local_mac[ETHERNET_ADDRESS_LENGTH];
- uint8_t peer_mac[ETHERNET_ADDRESS_LENGTH];
+ struct interface *ifp;
+ struct vrf *vrf;
+
+ int sock;
/* BFD session flags */
enum bfd_session_flags flags;
int type;
};
-struct bfd_vrf {
- int vrf_id;
- char name[MAXNAMELEN + 1];
-} bfd_vrf;
+struct bfd_session_observer {
+ struct bfd_session *bso_bs;
+ bool bso_isinterface;
+ bool bso_isaddress;
+ union {
+ char bso_entryname[MAXNAMELEN];
+ struct prefix bso_addr;
+ };
-struct bfd_iface {
- int vrf_id;
- char ifname[MAXNAMELEN + 1];
-} bfd_iface;
+ TAILQ_ENTRY(bfd_session_observer) bso_entry;
+};
+TAILQ_HEAD(obslist, bfd_session_observer);
/* States defined per 4.1 */
/* Various constants */
/* Retrieved from ptm_timer.h from Cumulus PTM sources. */
-#define MSEC_PER_SEC 1000L
-#define NSEC_PER_MSEC 1000000L
-
#define BFD_DEF_DEMAND 0
#define BFD_DEFDETECTMULT 3
-#define BFD_DEFDESIREDMINTX (300 * MSEC_PER_SEC)
-#define BFD_DEFREQUIREDMINRX (300 * MSEC_PER_SEC)
-#define BFD_DEF_REQ_MIN_ECHO (50 * MSEC_PER_SEC)
-#define BFD_DEF_SLOWTX (2000 * MSEC_PER_SEC)
+#define BFD_DEFDESIREDMINTX (300 * 1000) /* microseconds. */
+#define BFD_DEFREQUIREDMINRX (300 * 1000) /* microseconds. */
+#define BFD_DEF_REQ_MIN_ECHO (50 * 1000) /* microseconds. */
+#define BFD_DEF_SLOWTX (1000 * 1000) /* microseconds. */
#define BFD_DEF_MHOP_TTL 5
#define BFD_PKT_LEN 24 /* Length of control packet */
#define BFD_TTL_VAL 255
#define BFD_PKT_INFO_VAL 1
#define BFD_IPV6_PKT_INFO_VAL 1
#define BFD_IPV6_ONLY_VAL 1
-#define BFD_SRCPORTINIT 49142
-#define BFD_SRCPORTMAX 65536
+#define BFD_SRCPORTINIT 49152
+#define BFD_SRCPORTMAX 65535
#define BFD_DEFDESTPORT 3784
#define BFD_DEF_ECHO_PORT 3785
#define BFD_DEF_MHOP_DEST_PORT 4784
-#define BFD_CMD_STRING_LEN (MAXNAMELEN + 50)
-#define BFD_BUFFER_LEN (BFD_CMD_STRING_LEN + MAXNAMELEN + 1)
/*
* control.c
struct bcslist bg_bcslist;
struct pllist bg_pllist;
+
+ struct obslist bg_obslist;
};
extern struct bfd_global bglobal;
extern struct bfd_diag_str_list diag_list[];
int bp_udp_mhop(void);
int bp_udp6_shop(void);
int bp_udp6_mhop(void);
-int bp_peer_socket(struct bfd_peer_cfg *bpc);
-int bp_peer_socketv6(struct bfd_peer_cfg *bpc);
+int bp_peer_socket(const struct bfd_session *bs);
+int bp_peer_socketv6(const struct bfd_session *bs);
int bp_echo_socket(void);
int bp_echov6_socket(void);
*
* BFD protocol specific code.
*/
+int bfd_session_enable(struct bfd_session *bs);
+void bfd_session_disable(struct bfd_session *bs);
struct bfd_session *ptm_bfd_sess_new(struct bfd_peer_cfg *bpc);
int ptm_bfd_ses_del(struct bfd_peer_cfg *bpc);
void ptm_bfd_ses_dn(struct bfd_session *bfd, uint8_t diag);
void ptm_bfd_ses_up(struct bfd_session *bfd);
-void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen);
-void ptm_bfd_echo_stop(struct bfd_session *bfd, int polling);
+void ptm_bfd_echo_stop(struct bfd_session *bfd);
void ptm_bfd_echo_start(struct bfd_session *bfd);
void ptm_bfd_xmt_TO(struct bfd_session *bfd, int fbit);
void ptm_bfd_start_xmt_timer(struct bfd_session *bfd, bool is_echo);
-struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp, char *port_name,
+struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp,
struct sockaddr_any *peer,
struct sockaddr_any *local,
- char *vrf_name, bool is_mhop);
+ ifindex_t ifindex, vrf_id_t vrfid,
+ bool is_mhop);
struct bfd_session *bs_peer_find(struct bfd_peer_cfg *bpc);
int bfd_session_update_label(struct bfd_session *bs, const char *nlabel);
void bfd_set_polling(struct bfd_session *bs);
+void bs_state_handler(struct bfd_session *bs, int nstate);
+void bs_echo_timer_handler(struct bfd_session *bs);
+void bs_final_handler(struct bfd_session *bs);
+void bs_set_slow_timers(struct bfd_session *bs);
const char *satostr(struct sockaddr_any *sa);
const char *diag2str(uint8_t diag);
int strtosa(const char *addr, struct sockaddr_any *sa);
void integer2timestr(uint64_t time, char *buf, size_t buflen);
-const char *bs_to_string(struct bfd_session *bs);
+const char *bs_to_string(const struct bfd_session *bs);
+
+int bs_observer_add(struct bfd_session *bs);
+void bs_observer_del(struct bfd_session_observer *bso);
+
+void bs_to_bpc(struct bfd_session *bs, struct bfd_peer_cfg *bpc);
/* BFD hash data structures interface */
void bfd_initialize(void);
void bfd_shutdown(void);
struct bfd_session *bfd_id_lookup(uint32_t id);
-struct bfd_session *bfd_shop_lookup(struct bfd_shop_key shop);
-struct bfd_session *bfd_mhop_lookup(struct bfd_mhop_key mhop);
-struct bfd_vrf *bfd_vrf_lookup(int vrf_id);
-struct bfd_iface *bfd_iface_lookup(const char *ifname);
+struct bfd_session *bfd_key_lookup(struct bfd_key key);
struct bfd_session *bfd_id_delete(uint32_t id);
-struct bfd_session *bfd_shop_delete(struct bfd_shop_key shop);
-struct bfd_session *bfd_mhop_delete(struct bfd_mhop_key mhop);
-struct bfd_vrf *bfd_vrf_delete(int vrf_id);
-struct bfd_iface *bfd_iface_delete(const char *ifname);
+struct bfd_session *bfd_key_delete(struct bfd_key key);
bool bfd_id_insert(struct bfd_session *bs);
-bool bfd_shop_insert(struct bfd_session *bs);
-bool bfd_mhop_insert(struct bfd_session *bs);
-bool bfd_vrf_insert(struct bfd_vrf *vrf);
-bool bfd_iface_insert(struct bfd_iface *iface);
+bool bfd_key_insert(struct bfd_session *bs);
-typedef void (*hash_iter_func)(struct hash_backet *hb, void *arg);
+typedef void (*hash_iter_func)(struct hash_bucket *hb, void *arg);
void bfd_id_iterate(hash_iter_func hif, void *arg);
-void bfd_shop_iterate(hash_iter_func hif, void *arg);
-void bfd_mhop_iterate(hash_iter_func hif, void *arg);
-void bfd_vrf_iterate(hash_iter_func hif, void *arg);
-void bfd_iface_iterate(hash_iter_func hif, void *arg);
+void bfd_key_iterate(hash_iter_func hif, void *arg);
/* Export callback functions for `event.c`. */
extern struct thread_master *master;
int bfd_xmt_cb(struct thread *t);
int bfd_echo_xmt_cb(struct thread *t);
+extern struct in6_addr zero_addr;
+
/*
* bfdd_vty.c
int ptm_bfd_notify(struct bfd_session *bs);
-
-/*
- * OS compatibility functions.
- */
-#if defined(BFD_LINUX) || defined(BFD_BSD)
-int ptm_bfd_fetch_ifindex(const char *ifname);
-void ptm_bfd_fetch_local_mac(const char *ifname, uint8_t *mac);
-void fetch_portname_from_ifindex(int ifindex, char *ifname, size_t ifnamelen);
-#endif /* BFD_LINUX || BFD_BSD */
-
-#ifdef BFD_BSD
-ssize_t bsd_echo_sock_read(int sd, uint8_t *buf, ssize_t *buflen,
- struct sockaddr_storage *ss, socklen_t *sslen,
- uint8_t *ttl, uint32_t *id);
-#endif /* BFD_BSD */
-
#endif /* _BFD_H_ */