diff options
Diffstat (limited to 'zebra')
-rw-r--r-- | zebra/interface.c | 13 | ||||
-rw-r--r-- | zebra/zebra_ptm.c | 136 | ||||
-rw-r--r-- | zebra/zebra_ptm.h | 6 |
3 files changed, 106 insertions, 49 deletions
diff --git a/zebra/interface.c b/zebra/interface.c index 4329efd2a..9dc13f7b1 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -611,7 +611,7 @@ if_up (struct interface *ifp) struct prefix *p; /* Notify the protocol daemons. */ - if (ifp->ptm_enable && !ifp->ptm_status) { + if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) { zlog_warn("%s: interface %s hasn't passed ptm check\n", __func__, ifp->name); return; @@ -836,16 +836,7 @@ if_dump_vty (struct vty *vty, struct interface *ifp) vty_out (vty, "down%s", VTY_NEWLINE); } - vty_out (vty, " PTM status: "); - if (ifp->ptm_enable) { - if (ifp->ptm_status) { - vty_out (vty, "pass%s", VTY_NEWLINE); - } else { - vty_out (vty, "fail%s", VTY_NEWLINE); - } - } else { - vty_out (vty, "disabled%s", VTY_NEWLINE); - } + zebra_ptm_show_status(vty, ifp); if (ifp->desc) vty_out (vty, " Description: %s%s", ifp->desc, diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 0fecd17d5..039e80ddb 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -82,6 +82,8 @@ int zebra_ptm_sock_read(struct thread *); static void zebra_ptm_install_commands (void); static int zebra_ptm_handle_msg_cb(void *arg, void *in_ctxt); void zebra_bfd_peer_replay_req (void); +void zebra_ptm_send_status_req(void); +void zebra_ptm_reset_status(int ptm_disable); const char ZEBRA_PTM_SOCK_NAME[] = "\0/var/run/ptmd.socket"; @@ -161,6 +163,7 @@ zebra_ptm_flush_messages (struct thread *thread) safe_strerror (errno)); close(ptm_cb.ptm_sock); ptm_cb.ptm_sock = -1; + zebra_ptm_reset_status(0); ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time); return (-1); @@ -185,6 +188,7 @@ zebra_ptm_send_message(char *data, int size) zlog_warn ("%s ptm socket error: %s", __func__, safe_strerror (errno)); close(ptm_cb.ptm_sock); ptm_cb.ptm_sock = -1; + zebra_ptm_reset_status(0); ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time); return -1; @@ -204,8 +208,6 @@ int zebra_ptm_connect (struct thread *t) { int init = 0; - void *out_ctxt; - int len = ZEBRA_PTM_SEND_MAX_SOCKBUF; if (ptm_cb.ptm_sock == -1) { zebra_ptm_socket_init(); @@ -218,15 +220,7 @@ zebra_ptm_connect (struct thread *t) NULL, ptm_cb.ptm_sock); zebra_bfd_peer_replay_req(); } - - if (ptm_cb.ptm_enable) { - ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); - ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, - ZEBRA_PTM_GET_STATUS_CMD); - ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &len); - - zebra_ptm_send_message(ptm_cb.out_data, len); - } + zebra_ptm_send_status_req(); ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; } else { ptm_cb.reconnect_time *= 2; @@ -254,7 +248,8 @@ DEFUN (zebra_ptm_enable, if (!ifp->ptm_enable) { ifp->ptm_enable = 1; - ifp->ptm_status = 1; /* to bring down ports that may fail check */ + /* Assign a default unknown status */ + ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; } zebra_ptm_connect(NULL); @@ -268,28 +263,8 @@ DEFUN (no_zebra_ptm_enable, NO_STR "Enable neighbor check with specified topology\n") { - struct listnode *i; - struct interface *ifp; - int send_linkup; - ptm_cb.ptm_enable = 0; - for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp)) - { - if (ifp->ptm_enable) - { - if (!if_is_operative(ifp)) - send_linkup = 1; - - ifp->ptm_enable = 0; - if (if_is_operative (ifp) && send_linkup) { - if (IS_ZEBRA_DEBUG_EVENT) - zlog_debug ("%s: Bringing up interface %s", __func__, - ifp->name); - if_up (ifp); - } - } - } - + zebra_ptm_reset_status(1); return CMD_SUCCESS; } @@ -436,22 +411,30 @@ static int zebra_ptm_handle_cbl_msg(void *arg, void *in_ctxt, struct interface *ifp, char *cbl_str) { + int send_linkup = 0; + if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("%s: Recv Port [%s] cbl status [%s]", __func__, ifp->name, cbl_str); - if (!strcmp(cbl_str, ZEBRA_PTM_PASS_STR) && (!ifp->ptm_status)) { - ifp->ptm_status = 1; - if (ifp->ptm_enable && if_is_no_ptm_operative (ifp)) + if (!strcmp(cbl_str, ZEBRA_PTM_PASS_STR) && + (ifp->ptm_status != ZEBRA_PTM_STATUS_UP)) { + + if (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN) + send_linkup = 1; + ifp->ptm_status = ZEBRA_PTM_STATUS_UP; + if (ifp->ptm_enable && if_is_no_ptm_operative (ifp) && send_linkup) if_up (ifp); - } else if (!strcmp (cbl_str, ZEBRA_PTM_FAIL_STR) && (ifp->ptm_status)) { - ifp->ptm_status = 0; + } else if (!strcmp (cbl_str, ZEBRA_PTM_FAIL_STR) && + (ifp->ptm_status != ZEBRA_PTM_STATUS_DOWN)) { + ifp->ptm_status = ZEBRA_PTM_STATUS_DOWN; if (ifp->ptm_enable && if_is_no_ptm_operative (ifp)) if_down (ifp); } return 0; } + /* * zebra_ptm_handle_msg_cb - The purpose of this callback function is to handle * all the command responses and notifications received from PTM. @@ -541,6 +524,7 @@ zebra_ptm_sock_read (struct thread *thread) close (ptm_cb.ptm_sock); ptm_cb.ptm_sock = -1; + zebra_ptm_reset_status(0); ptm_cb.t_timer = thread_add_timer (zebrad.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time); return (-1); @@ -861,3 +845,79 @@ zebra_ptm_get_enable_state(void) { return ptm_cb.ptm_enable; } + +/* + * zebra_ptm_get_status_str - Convert status to a display string. + */ +static const char * +zebra_ptm_get_status_str(int status) +{ + switch (status) + { + case ZEBRA_PTM_STATUS_DOWN: + return "fail"; + case ZEBRA_PTM_STATUS_UP: + return "pass"; + case ZEBRA_PTM_STATUS_UNKNOWN: + default: + return "n/a"; + } +} + +void +zebra_ptm_show_status(struct vty *vty, struct interface *ifp) +{ + vty_out (vty, " PTM status: "); + if (ifp->ptm_enable) { + vty_out (vty, "%s%s", zebra_ptm_get_status_str (ifp->ptm_status), + VTY_NEWLINE); + } else { + vty_out (vty, "disabled%s", VTY_NEWLINE); + } +} + +void +zebra_ptm_send_status_req(void) +{ + void *out_ctxt; + int len = ZEBRA_PTM_SEND_MAX_SOCKBUF; + + if (ptm_cb.ptm_enable) + { + ptm_lib_init_msg(ptm_hdl, 0, PTMLIB_MSG_TYPE_CMD, NULL, &out_ctxt); + ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_CMD_STR, + ZEBRA_PTM_GET_STATUS_CMD); + ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &len); + + zebra_ptm_send_message(ptm_cb.out_data, len); + } +} + +void +zebra_ptm_reset_status(int ptm_disable) +{ + struct listnode *i; + struct interface *ifp; + int send_linkup; + + for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp)) + { + send_linkup = 0; + if (ifp->ptm_enable) + { + if (!if_is_operative(ifp)) + send_linkup = 1; + + if (ptm_disable) + ifp->ptm_enable = 0; + ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; + + if (if_is_operative (ifp) && send_linkup) { + if (IS_ZEBRA_DEBUG_EVENT) + zlog_debug ("%s: Bringing up interface %s", __func__, + ifp->name); + if_up (ifp); + } + } + } +} diff --git a/zebra/zebra_ptm.h b/zebra/zebra_ptm.h index e26edf092..6767d822e 100644 --- a/zebra/zebra_ptm.h +++ b/zebra/zebra_ptm.h @@ -46,6 +46,10 @@ struct zebra_ptm_cb int pid; }; +#define ZEBRA_PTM_STATUS_DOWN 0 +#define ZEBRA_PTM_STATUS_UP 1 +#define ZEBRA_PTM_STATUS_UNKNOWN 2 + void zebra_ptm_init (void); void zebra_ptm_finish(void); int zebra_ptm_connect (struct thread *t); @@ -55,4 +59,6 @@ int zebra_ptm_get_enable_state(void); int zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, int command); int zebra_ptm_bfd_dst_deregister (struct zserv *client, int sock, u_short length); +void +zebra_ptm_show_status(struct vty *vty, struct interface *ifp); #endif |