/* BGP keepalive fire ! */ static int bgp_keepalive_timer (struct thread *thread) { struct peer *peer; peer = THREAD_ARG (thread); peer->t_keepalive = NULL; if (BGP_DEBUG (fsm, FSM)) zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (keepalive timer expire)", peer->host); THREAD_VAL (thread) = KeepAlive_timer_expired; bgp_event (thread); /* bgp_event unlocks peer */ return 0; }
int ospf_hello_timer(struct thread *thread) { struct ospf_interface *oi; oi = THREAD_ARG(thread); oi->t_hello = NULL; if (IS_DEBUG_OSPF(ism, ISM_TIMERS)) zlog(NULL, LOG_DEBUG, "ISM[%s]: Timer (Hello timer expire)", IF_NAME(oi)); /* Sending hello packet. */ ospf_hello_send(oi); /* Hello timer set. */ OSPF_HELLO_TIMER_ON(oi); return 0; }
int isis_adj_expire (struct thread *thread) { struct isis_adjacency *adj; int level; /* * Get the adjacency */ adj = THREAD_ARG (thread); assert (adj); level = adj->level; adj->t_expire = NULL; /* trigger the adj expire event */ isis_adj_state_change (adj, ISIS_ADJ_DOWN, "holding time expired"); return 0; }
int ospf6_bfd_down (struct thread *thread) { struct ospf6_neighbor *on; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *BFD Down*", on->name); on->drouter = on->prev_drouter = 0; on->bdrouter = on->prev_bdrouter = 0; ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on); thread_add_event (master, neighbor_change, on->ospf6_if, 0); return 0; }
int hello_received(struct thread * thread) { struct ospf6_neighbor * on; on = THREAD_ARG(thread); assert(on); printf("Hello Received\n"); /* reset Inactivity Timer */ THREAD_OFF (on->inactivity_timer); on->inactivity_timer = thread_add_timer (master, inactivity_timer, on, on->ospf6_if->dead_interval); if(on->state <= OSPF6_NEIGHBOR_DOWN) ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on); return 0; }
/* Execute event process. */ int bgp_event (struct thread *thread) { int ret = 0; int event; int next; struct peer *peer; peer = THREAD_ARG (thread); event = THREAD_VAL (thread); /* Logging this event. */ next = FSM [peer->status -1][event - 1].next_state; if (BGP_DEBUG (fsm, FSM) && peer->status != next) plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host, bgp_event_str[event], LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)); /* Call function. */ if (FSM [peer->status -1][event - 1].func) ret = (*(FSM [peer->status - 1][event - 1].func))(peer); /* When function do not want proceed next job return -1. */ if (ret >= 0) { /* If status is changed. */ if (next != peer->status) { /* Transition into Clearing must /always/ clear all routes.. */ if (next == Clearing) bgp_clear_route_all (peer); bgp_fsm_change_status (peer, next); } /* Make sure timer is set. */ bgp_timer_set (peer); } return ret; }
int neighbor_change (struct thread *thread) { struct ospf6_interface *oi; oi = (struct ospf6_interface *) THREAD_ARG (thread); assert (oi && oi->interface); if (IS_OSPF6_DEBUG_INTERFACE) zlog_debug ("Interface Event %s: [NeighborChange]", oi->interface->name); if (oi->state == OSPF6_INTERFACE_DROTHER || oi->state == OSPF6_INTERFACE_BDR || oi->state == OSPF6_INTERFACE_DR) ospf6_interface_state_change (dr_election (oi), oi); return 0; }
/* BGP start timer. This function set BGP_Start event to thread value and process event. */ static int bgp_start_timer (struct thread *thread) { struct peer *peer; peer = THREAD_ARG (thread); peer->t_start = NULL; UNSET_FLAG (peer->sflags, PEER_STATUS_CREATE_INIT); if (BGP_DEBUG (fsm, FSM)) zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (start timer expire).", peer->host); THREAD_VAL (thread) = BGP_Start; bgp_event (thread); return 0; }
//周期性发送hello low数据包 int hello_low_send(struct thread * thread) { struct backbone_eth* eth = (struct backbone_eth *)THREAD_ARG(thread); struct hello_low* hello_low = (struct hello_low*)sendbuf; struct hello_master* hello_master = eth->hello_master; hello_master->hello_timer_low = thread_add_timer_high_resolution(master, hello_low_send, eth, TMP_VAR * hello_master->l_hello_val); memset(sendbuf, 0, MAX_MESSAGE_LEN); hello_low->lsd_head.pktype = IC_MESSAGE_TYPE_HELLO_L; hello_low->lsd_head.pklen = sizeof(struct hello_low); hello_low->dead_interval = TMP_VAR * hello_master->l_dead_val; hello_low->hello_interval = TMP_VAR * hello_master->l_hello_val; lsd_send(eth, (struct lsd_head *)sendbuf); return 0; }
enum connect_result tcp_socket_state(int fd, thread_t * thread, int (*func) (thread_t *)) { int status; socklen_t addrlen; int ret = 0; timeval_t timer_min; /* Handle connection timeout */ if (thread->type == THREAD_WRITE_TIMEOUT) { close(thread->u.fd); return connect_timeout; } /* Check file descriptor */ addrlen = sizeof(status); if (getsockopt(thread->u.fd, SOL_SOCKET, SO_ERROR, (void *) &status, &addrlen) < 0) ret = errno; /* Connection failed !!! */ if (ret) { close(thread->u.fd); return connect_error; } /* If status = 0, TCP connection to remote host is established. * Otherwise register checker thread to handle connection in progress, * and other error code until connection is established. * Recompute the write timeout (or pending connection). */ if (status == EINPROGRESS) { timer_min = timer_sub_now(thread->sands); thread_add_write(thread->master, func, THREAD_ARG(thread), thread->u.fd, timer_long(timer_min)); return connect_in_progress; } else if (status != 0) { close(thread->u.fd); return connect_error; } return connect_success; }
/* Execute event process. */ int bgp_event (struct thread *thread) { int ret; int event; int next; struct peer *peer; peer = THREAD_ARG (thread); event = THREAD_VAL (thread); /* Logging this event. */ next = FSM [peer->status -1][event - 1].next_state; if (BGP_DEBUG (fsm, FSM)) plog_info (peer->log, "%s [FSM] %s (%s->%s)", peer->host, bgp_event_str[event], LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)); if (BGP_DEBUG (normal, NORMAL) && strcmp (LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next))) zlog_info ("%s went from %s to %s", peer->host, LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)); /* Call function. */ ret = (*(FSM [peer->status - 1][event - 1].func))(peer); /* When function do not want proceed next job return -1. */ if (ret < 0) return ret; /* If status is changed. */ if (next != peer->status) bgp_fsm_change_status (peer, next); /* Make sure timer is set. */ bgp_timer_set (peer); return 0; }
/* Asynchronous HTTP stream reader */ int http_read_thread(thread_t * thread) { SOCK *sock_obj = THREAD_ARG(thread); int r = 0; /* Handle read timeout */ if (thread->type == THREAD_READ_TIMEOUT) return epilog(thread); /* read the HTTP stream */ memset(sock_obj->buffer, 0, MAX_BUFFER_LENGTH); r = read(thread->u.fd, sock_obj->buffer + sock_obj->size, MAX_BUFFER_LENGTH - sock_obj->size); DBG(" [l:%d,fd:%d]\n", r, sock_obj->fd); if (r == -1 || r == 0) { /* -1:error , 0:EOF */ if (r == -1) { /* We have encourred a real read error */ DBG("Read error with server [%s]:%d: %s\n", inet_ntop2(req->addr_ip), ntohs(req->addr_port), strerror(errno)); return epilog(thread); } /* All the HTTP stream has been parsed */ finalize(thread); } else { /* Handle the response stream */ http_process_stream(sock_obj, r); /* * Register next http stream reader. * Register itself to not perturbe global I/O multiplexer. */ thread_add_read(thread->master, http_read_thread, sock_obj, thread->u.fd, HTTP_CNX_TIMEOUT); } return 0; }
/* RCPT command processing */ static int rcpt_cmd(thread_t * thread) { smtp_t *smtp = THREAD_ARG(thread); char *buffer; char *fetched_email; buffer = (char *) MALLOC(SMTP_BUFFER_MAX); /* We send RCPT TO command multiple time to add all our email receivers. * --rfc821.3.1 */ fetched_email = fetch_next_email(smtp); snprintf(buffer, SMTP_BUFFER_MAX, SMTP_RCPT_CMD, fetched_email); if (send(thread->u.fd, buffer, strlen(buffer), 0) == -1) smtp->stage = ERROR; FREE(buffer); return 0; }
static int lsa_delete (struct thread *t) { struct ospf_apiclient *oclient; struct in_addr area_id; int rc; oclient = THREAD_ARG (t); inet_aton (args[6], &area_id); printf ("Deleting LSA... "); rc = ospf_apiclient_lsa_delete (oclient, area_id, atoi (args[2]), /* lsa type */ atoi (args[3]), /* opaque type */ atoi (args[4])); /* opaque ID */ printf ("done, return code is = %d\n", rc); return rc; }
int loading_done (struct thread *thread) { struct ospf6_neighbor *on; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (on->state != OSPF6_NEIGHBOR_LOADING) return 0; if (IS_OSPF6_SIBLING_DEBUG_NEIGHBOR) zlog_debug ("Neighbor Event %s: *LoadingDone*", on->name); assert (on->request_list->count == 0); ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on); return 0; }
int bgp_routeadv_timer_vpnv4_unicast (struct thread *thread) { struct peer *peer; peer = THREAD_ARG (thread); peer->t_routeadv[AFI_IP][SAFI_MPLS_VPN] = NULL; if (BGP_DEBUG (events, EVENTS)) zlog_info ("%s routeadv timer expired for VPNv4 unicast", peer->host); peer->synctime[AFI_IP][SAFI_MPLS_VPN] = time (NULL); BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); BGP_TIMER_ON (peer->t_routeadv[AFI_IP][SAFI_MPLS_VPN], bgp_routeadv_timer_vpnv4_unicast, peer->v_routeadv); return 0; }
/* RFC-3618:Sec-5.4 - peer hold timer */ static int pim_msdp_peer_hold_timer_cb(struct thread *t) { struct pim_msdp_peer *mp; mp = THREAD_ARG(t); if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_timer_expiry_log(mp, "hold"); } if (mp->state != PIM_MSDP_ESTABLISHED) { return 0; } if (PIM_DEBUG_MSDP_EVENTS) { pim_msdp_peer_state_chg_log(mp); } pim_msdp_peer_reset_tcp_conn(mp, "ht-expired"); return 0; }
/* RFC 3376: 6.5. Switching Router Filter-Modes When a router's filter-mode for a group is EXCLUDE and the group timer expires, the router filter-mode for the group transitions to INCLUDE. A router uses source records with running source timers as its state for the switch to a filter-mode of INCLUDE. If there are any source records with source timers greater than zero (i.e., requested to be forwarded), a router switches to filter-mode of INCLUDE using those source records. Source records whose timers are zero (from the previous EXCLUDE mode) are deleted. */ static int igmp_group_timer(struct thread *t) { struct igmp_group *group; zassert(t); group = THREAD_ARG(t); zassert(group); if (PIM_DEBUG_IGMP_TRACE) { char group_str[100]; pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str)); zlog_debug("%s: Timer for group %s on interface %s", __PRETTY_FUNCTION__, group_str, group->group_igmp_sock->interface->name); } zassert(group->group_filtermode_isexcl); group->t_group_timer = 0; group->group_filtermode_isexcl = 0; /* Any source (*,G) is forwarded only if mode is EXCLUDE {empty} */ igmp_anysource_forward_stop(group); igmp_source_delete_expired(group->group_source_list); zassert(!group->t_group_timer); zassert(!group->group_filtermode_isexcl); /* RFC 3376: 6.2.2. Definition of Group Timers If there are no more source records for the group, delete group record. */ if (listcount(group->group_source_list) < 1) { igmp_group_delete_empty_include(group); } return 0; }
int hello_received (struct thread *thread) { struct ospf6_neighbor *on; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *HelloReceived*", on->name); /* reset Inactivity Timer */ THREAD_OFF (on->inactivity_timer); on->inactivity_timer = thread_add_timer (master, inactivity_timer, on, on->ospf6_if->dead_interval); if (on->state <= OSPF6_NEIGHBOR_DOWN) ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on); return 0; }
/* Connect to zebra for nexthop lookup. */ static int zlookup_connect (struct thread *t) { struct zclient *zlookup; zlookup = THREAD_ARG (t); zlookup->t_connect = NULL; if (zlookup->sock != -1) return 0; #ifdef HAVE_TCP_ZEBRA zlookup->sock = zclient_socket (); #else zlookup->sock = zclient_socket_un (ZEBRA_SERV_PATH); #endif /* HAVE_TCP_ZEBRA */ if (zlookup->sock < 0) return -1; return 0; }
static int bgp_graceful_stale_timer_expire (struct thread *thread) { struct peer *peer; afi_t afi; safi_t safi; peer = THREAD_ARG (thread); peer->t_gr_stale = NULL; if (BGP_DEBUG (events, EVENTS)) zlog_debug ("%s graceful restart stalepath timer expired", peer->host); /* NSF delete stale route */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_RESERVED_3 ; safi++) if (peer->nsf[afi][safi]) bgp_clear_stale_route (peer, afi, safi); return 0; }
static int ospf_db_desc_timer (struct thread *thread) { struct ospf_neighbor *nbr; nbr = THREAD_ARG (thread); nbr->t_db_desc = NULL; if (IS_DEBUG_OSPF (nsm, NSM_TIMERS)) zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (DD Retransmit timer expire)", IF_NAME (nbr->oi), inet_ntoa (nbr->src)); /* resent last send DD packet. */ assert (nbr->last_send); ospf_db_desc_resend (nbr); /* DD Retransmit timer set. */ OSPF_NSM_TIMER_ON (nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc); return 0; }
int ppp_tcp_read(struct thread *thread) { struct ppp_mcp_sock *peer; //int data_len; /* Yes first of all get peer pointer. */ peer = THREAD_ARG (thread); peer->t_read = NULL; if (peer->fd < 0) { PPPD_DEBUG_TCP("read: peer's fd is negative value %d", peer->fd); return -1; } MCP_READ_ON (peer->t_read, ppp_tcp_read, peer, peer->fd); if (peer->packet_size == 0) peer->packet_size = MCP_PPP_HEADER_SIZE; if (stream_get_endp (peer->ibuf) < MCP_PPP_HEADER_SIZE) { if(mcp_pppd_read(peer) == -1) return 0; peer->packet_size = stream_getl(peer->ibuf); peer->control_cmd = stream_getl(peer->ibuf); } if(mcp_pppd_read(peer) == -1) { PPPD_DEBUG_TCP("ppp read tcp error:%s", peer->hostname); return 0; } mcp_pppd_tcp_read_deal(peer); stream_reset (peer->ibuf); peer->packet_size = 0; pppd_postpone_holdtime_timer(peer); return 0; }
int mplsd_read(struct thread *thread) { int retval; struct ldp *ldp = ldp_get(); mpls_socket_handle socket; MPLS_ASSERT(thread); socket = THREAD_ARG(thread); socket->read = thread_add_read(master,mplsd_read,socket,socket->fd); if (!ldp) { return 0; } switch (socket->type) { case MPLS_SOCKET_TCP_DATA: { retval = ldp_event(ldp->h, socket, socket->extra, LDP_EVENT_TCP_DATA); break; } case MPLS_SOCKET_TCP_LISTEN: { retval = ldp_event(ldp->h, socket, socket->extra, LDP_EVENT_TCP_LISTEN); break; } case MPLS_SOCKET_UDP_DATA: { retval = ldp_event(ldp->h, socket, socket->extra, LDP_EVENT_UDP_DATA); break; } default: { assert(0); } } return 0; }
int adj_ok (struct thread *thread) { struct ospf6_neighbor *on; struct ospf6_lsa *lsa; on = (struct ospf6_neighbor *) THREAD_ARG (thread); assert (on); if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT)) zlog_info ("Neighbor Event %s: *AdjOK?*", on->name); if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on)) { ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT); SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT); THREAD_OFF (on->thread_send_dbdesc); on->thread_send_dbdesc = thread_add_event (master, ospf6_dbdesc_send, on, 0); } else if (on->state >= OSPF6_NEIGHBOR_EXSTART && ! need_adjacency (on)) { ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on); ospf6_lsdb_remove_all (on->summary_list); ospf6_lsdb_remove_all (on->request_list); for (lsa = ospf6_lsdb_head (on->retrans_list); lsa; lsa = ospf6_lsdb_next (lsa)) { ospf6_decrement_retrans_count (lsa); ospf6_lsdb_remove (lsa, on->retrans_list); } } return 0; }
int tcp_connection_state(int fd, enum connect_result status, thread_t * thread, int (*func) (thread_t *), long timeout) { checker_t *checker; checker = THREAD_ARG(thread); switch (status) { case connect_success: thread_add_write(thread->master, func, checker, fd, timeout); return 0; /* Checking non-blocking connect, we wait until socket is writable */ case connect_in_progress: thread_add_write(thread->master, func, checker, fd, timeout); return 0; default: return 1; } }
static int bgp_routeadv_timer (struct thread *thread) { struct peer *peer; peer = THREAD_ARG (thread); peer->t_routeadv = NULL; if (BGP_DEBUG (fsm, FSM)) zlog (peer->log, LOG_DEBUG, "%s [FSM] Timer (routeadv timer expire)", peer->host); peer->synctime = bgp_clock (); BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); BGP_TIMER_ON (peer->t_routeadv, bgp_routeadv_timer, peer->v_routeadv); return 0; }
/* Periodic hello timer */ static int on_pim_hello_send(struct thread *t) { struct pim_interface *pim_ifp; struct interface *ifp; zassert(t); ifp = THREAD_ARG(t); zassert(ifp); pim_ifp = ifp->info; /* * Schedule next hello */ pim_ifp->t_pim_hello_timer = 0; hello_resched(ifp); /* * Send hello */ return pim_hello_send(ifp, PIM_IF_DEFAULT_HOLDTIME(pim_ifp)); }
static int if_linkbeat_refresh_thread(thread_t * thread) { interface_t *ifp = THREAD_ARG(thread); if (IF_MII_SUPPORTED(ifp)) ifp->linkbeat = (if_mii_probe(ifp->ifname)) ? 1 : 0; else if (IF_ETHTOOL_SUPPORTED(ifp)) ifp->linkbeat = (if_ethtool_probe(ifp->ifname)) ? 1 : 0; else ifp->linkbeat = 1; /* * update ifp->flags to get the new IFF_RUNNING status. * Some buggy drivers need this... */ if_ioctl_flags(ifp); /* Register next polling thread */ thread_add_timer(master, if_linkbeat_refresh_thread, ifp, POLLING_DELAY); return 0; }
/* BGP Network Routes Scan */ s_int32_t bnh_network_scan (struct thread *t_network_scan) { struct lib_globals *blg; struct bgp *bgp; s_int32_t ret; ret = 0; bgp = THREAD_ARG (t_network_scan); blg = THREAD_GLOB (t_network_scan); if (! blg || &BLG != blg || ! bgp) { ret = -1; goto EXIT; } bgp->t_network_scan = NULL; BGP_SET_VR_CONTEXT (&BLG, bgp->owning_bvr); if (BGP_DEBUG (normal, NORMAL)) zlog_info (&BLG, "[RIB] Scanning BGP Network Routes..."); bnh_network_scan_afi (bgp, AFI_IP); #ifdef HAVE_IPV6 IF_BGP_CAP_HAVE_IPV6 bnh_network_scan_afi (bgp, AFI_IP6); #endif /* HAVE_IPV6 */ if (bgp->network_scan_interval) BGP_TIMER_ON (&BLG, bgp->t_network_scan, bgp, bnh_network_scan, bgp->network_scan_interval); EXIT: return ret; }