/* TCP connection open. Next we send open message to remote peer. And add read thread for reading open message. */ static int bgp_connect_success (struct peer *peer) { char buf1[BUFSIZ]; if (peer->fd < 0) { zlog_err ("bgp_connect_success peer's fd is negative value %d", peer->fd); return -1; } BGP_READ_ON (peer->t_read, bgp_read, peer->fd); if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) bgp_getsockname (peer); if (BGP_DEBUG (normal, NORMAL)) { if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) zlog_debug ("%s open active, local address %s", peer->host, sockunion2str (peer->su_local, buf1, SU_ADDRSTRLEN)); else zlog_debug ("%s passive open", peer->host); } if (! CHECK_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER)) bgp_open_send (peer); return 0; }
/* * Set MD5 key for the socket, for the given IPv4 peer address. * If the password is NULL or zero-length, the option will be disabled. */ static int bgp_md5_set_socket(int socket, union sockunion *su, uint16_t prefixlen, const char *password) { int ret = -1; int en = ENOSYS; #if HAVE_DECL_TCP_MD5SIG union sockunion su2; #endif /* HAVE_TCP_MD5SIG */ assert(socket >= 0); #if HAVE_DECL_TCP_MD5SIG /* Ensure there is no extraneous port information. */ memcpy(&su2, su, sizeof(union sockunion)); if (su2.sa.sa_family == AF_INET) su2.sin.sin_port = 0; else su2.sin6.sin6_port = 0; /* For addresses, use the non-extended signature functionality */ if ((su2.sa.sa_family == AF_INET && prefixlen == IPV4_MAX_PREFIXLEN) || (su2.sa.sa_family == AF_INET6 && prefixlen == IPV6_MAX_PREFIXLEN)) ret = sockopt_tcp_signature(socket, &su2, password); else ret = sockopt_tcp_signature_ext(socket, &su2, prefixlen, password); en = errno; #endif /* HAVE_TCP_MD5SIG */ if (ret < 0) { char sabuf[SU_ADDRSTRLEN]; sockunion2str(su, sabuf, sizeof(sabuf)); switch (ret) { case -2: flog_warn( EC_BGP_NO_TCP_MD5, "Unable to set TCP MD5 option on socket for peer %s (sock=%d): This platform does not support MD5 auth for prefixes", sabuf, socket); break; default: flog_warn( EC_BGP_NO_TCP_MD5, "Unable to set TCP MD5 option on socket for peer %s (sock=%d): %s", sabuf, socket, safe_strerror(en)); } } return ret; }
s32 ws__showBgpNeighbor(WS_ENV * ws_env,s32 afi, s32 safi,s32 nstart, s32 nsize,struct BgpShowNeighborResponse * ret) { s8 temp[SU_ADDRSTRLEN]; s32 count = 0 , i = 0; s32 sum = 0 ; s32 max = 0; struct BgpShowNeighbor * out = NULL; web_bgp_neighbor_show_info_t * info = (void*)buff; if( socket_api_write(WEB_BGP_APICMD_SHOW_NBR,NULL,0) < 0 ) return ws_send_soap_error(ws_env,"send command error!"); do{ count = socket_api_read(WEB_BGP_APICMD_SHOW_NBR,info,SOCKET_API_BUFFER_SIZE); if( count <= 0 ) { break; } if( max < sum + count ) { void * tmp = ws_malloc(ws_env,(sum + count)*sizeof(struct BgpShowNeighbor)); if( out != NULL ) { memcpy(tmp,out,sum * sizeof(struct BgpShowNeighbor)); ws_free(ws_env,out); } out = tmp ; max = sum + count ; } for(i=0;i<count;i++) { out[sum].hostip = ws_strdup(ws_env, sockunion2str(&(info[i].su), temp, SU_ADDRSTRLEN) ) ; out[sum].asid = info[i].asid ; out[sum].hostid = ws_strdup(ws_env,inet_ntoa(info[i].id)); out[sum].state = ws_strdup(ws_env,bgp_status_msg[(s32)info[i].state]); out[sum].localinterface = ws_strdup(ws_env,inet_ntoa(info[i].nexthop)); out[sum].uptime = ws_strdup(ws_env,web_time_dump(info[i].t_uptime)); out[sum].overtime = ws_strdup(ws_env,web_time_dump(info[i].t_dead)); sum++; } }while( ! socket_api_check_flag(SOCKET_API_FLAG_LASTONE) ); ret->ret.sum = sum ; ret->ret.__ptrres = out ; ret->ret.__size = sum ; ret->ret.res_USCOREcount = sum ; return WS_OK; }
int nhrp_route_read(ZAPI_CALLBACK_ARGS) { struct zapi_route api; struct zapi_nexthop *api_nh; struct interface *ifp = NULL; union sockunion nexthop_addr; char buf[2][PREFIX_STRLEN]; int added; if (zapi_route_decode(zclient->ibuf, &api) < 0) return -1; /* we completely ignore srcdest routes for now. */ if (CHECK_FLAG(api.message, ZAPI_MESSAGE_SRCPFX)) return 0; sockunion_family(&nexthop_addr) = AF_UNSPEC; if (CHECK_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP)) { api_nh = &api.nexthops[0]; nexthop_addr.sa.sa_family = api.prefix.family; switch (nexthop_addr.sa.sa_family) { case AF_INET: nexthop_addr.sin.sin_addr = api_nh->gate.ipv4; break; case AF_INET6: nexthop_addr.sin6.sin6_addr = api_nh->gate.ipv6; break; } if (api_nh->ifindex != IFINDEX_INTERNAL) ifp = if_lookup_by_index(api_nh->ifindex, VRF_DEFAULT); } added = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD); debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %s via %s dev %s", added ? "add" : "del", prefix2str(&api.prefix, buf[0], sizeof buf[0]), sockunion2str(&nexthop_addr, buf[1], sizeof buf[1]), ifp ? ifp->name : "(none)"); nhrp_route_update_zebra(&api.prefix, &nexthop_addr, ifp); nhrp_shortcut_prefix_change(&api.prefix, !added); return 0; }
static void nhrp_interface_interface_notifier(struct notifier_block *n, unsigned long cmd) { struct nhrp_interface *nifp = container_of(n, struct nhrp_interface, nbmanifp_notifier); struct interface *nbmaifp = nifp->nbmaifp; struct nhrp_interface *nbmanifp = nbmaifp->info; char buf[SU_ADDRSTRLEN]; switch (cmd) { case NOTIFY_INTERFACE_CHANGED: nhrp_interface_update_mtu(nifp->ifp, AFI_IP); nhrp_interface_update_source(nifp->ifp); break; case NOTIFY_INTERFACE_ADDRESS_CHANGED: nifp->nbma = nbmanifp->afi[AFI_IP].addr; nhrp_interface_update(nifp->ifp); notifier_call(&nifp->notifier_list, NOTIFY_INTERFACE_NBMA_CHANGED); debugf(NHRP_DEBUG_IF, "%s: NBMA change: address %s", nifp->ifp->name, sockunion2str(&nifp->nbma, buf, sizeof buf)); break; } }
/* passive peer socket accept */ static int pim_msdp_sock_accept(struct thread *thread) { union sockunion su; struct pim_instance *pim = THREAD_ARG(thread); int accept_sock; int msdp_sock; struct pim_msdp_peer *mp; char buf[SU_ADDRSTRLEN]; sockunion_init(&su); /* re-register accept thread */ accept_sock = THREAD_FD(thread); if (accept_sock < 0) { flog_err(LIB_ERR_DEVELOPMENT, "accept_sock is negative value %d", accept_sock); return -1; } pim->msdp.listener.thread = NULL; thread_add_read(master, pim_msdp_sock_accept, pim, accept_sock, &pim->msdp.listener.thread); /* accept client connection. */ msdp_sock = sockunion_accept(accept_sock, &su); if (msdp_sock < 0) { flog_err_sys(LIB_ERR_SOCKET, "pim_msdp_sock_accept failed (%s)", safe_strerror(errno)); return -1; } /* see if have peer config for this */ mp = pim_msdp_peer_find(pim, su.sin.sin_addr); if (!mp || !PIM_MSDP_PEER_IS_LISTENER(mp)) { ++pim->msdp.rejected_accepts; if (PIM_DEBUG_MSDP_EVENTS) { flog_err(PIM_ERR_MSDP_PACKET, "msdp peer connection refused from %s", sockunion2str(&su, buf, SU_ADDRSTRLEN)); } close(msdp_sock); return -1; } if (PIM_DEBUG_MSDP_INTERNAL) { zlog_debug("MSDP peer %s accept success%s", mp->key_str, mp->fd >= 0 ? "(dup)" : ""); } /* if we have an existing connection we need to kill that one * with this one */ if (mp->fd >= 0) { if (PIM_DEBUG_MSDP_EVENTS) { zlog_notice( "msdp peer new connection from %s stop old connection", sockunion2str(&su, buf, SU_ADDRSTRLEN)); } pim_msdp_peer_stop_tcp_conn(mp, true /* chg_state */); } mp->fd = msdp_sock; set_nonblocking(mp->fd); pim_msdp_update_sock_send_buffer_size(mp->fd); pim_msdp_peer_established(mp); return 0; }
/* Accept bgp connection. */ static int bgp_accept (struct thread *thread) { int bgp_sock; int accept_sock; union sockunion su; struct bgp_listener *listener = THREAD_ARG(thread); struct peer *peer; struct peer *peer1; char buf[SU_ADDRSTRLEN]; /* Register accept thread. */ accept_sock = THREAD_FD (thread); if (accept_sock < 0) { zlog_err ("accept_sock is nevative value %d", accept_sock); return -1; } listener->thread = thread_add_read (master, bgp_accept, listener, accept_sock); /* Accept client connection. */ bgp_sock = sockunion_accept (accept_sock, &su); if (bgp_sock < 0) { zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno)); return -1; } set_nonblocking (bgp_sock); /* Set socket send buffer size */ bgp_update_sock_send_buffer_size(bgp_sock); if (BGP_DEBUG (events, EVENTS)) zlog_debug ("[Event] BGP connection from host %s", inet_sutop (&su, buf)); /* Check remote IP address */ peer1 = peer_lookup (NULL, &su); if (! peer1 || peer1->status == Idle) { if (BGP_DEBUG (events, EVENTS)) { if (! peer1) zlog_debug ("[Event] BGP connection IP address %s is not configured", inet_sutop (&su, buf)); else zlog_debug ("[Event] BGP connection IP address %s is Idle state", inet_sutop (&su, buf)); } close (bgp_sock); return -1; } bgp_set_socket_ttl (peer1, bgp_sock); /* Make dummy peer until read Open packet. */ if (BGP_DEBUG (events, EVENTS)) zlog_debug ("[Event] Make dummy peer structure until read Open packet"); { char buf[SU_ADDRSTRLEN]; peer = peer_create_accept (peer1->bgp); SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER); peer->su = su; peer->fd = bgp_sock; peer->status = Active; peer->local_id = peer1->local_id; peer->v_holdtime = peer1->v_holdtime; peer->v_keepalive = peer1->v_keepalive; /* Make peer's address string. */ sockunion2str (&su, buf, SU_ADDRSTRLEN); peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf); } BGP_EVENT_ADD (peer, TCP_connection_open); return 0; }
/* Accept bgp connection. */ static int bgp_accept (struct thread *thread) { int bgp_sock; int accept_sock; union sockunion su; struct peer *peer; struct peer *peer1; struct bgp *bgp; char buf[SU_ADDRSTRLEN]; /* Regiser accept thread. */ accept_sock = THREAD_FD (thread); bgp = THREAD_ARG (thread); if (accept_sock < 0) { zlog_err ("accept_sock is nevative value %d", accept_sock); return -1; } thread_add_read (master, bgp_accept, bgp, accept_sock); /* Accept client connection. */ bgp_sock = sockunion_accept (accept_sock, &su); if (bgp_sock < 0) { zlog_err ("[Error] BGP socket accept failed (%s)", strerror (errno)); return -1; } if (BGP_DEBUG (events, EVENTS)) zlog_info ("[Event] BGP connection from host %s", inet_sutop (&su, buf)); /* Check remote IP address */ peer1 = peer_lookup (bgp, &su); if (! peer1 || peer1->status == Idle) { if (BGP_DEBUG (events, EVENTS)) { if (! peer1) zlog_info ("[Event] BGP connection IP address %s is not configured", inet_sutop (&su, buf)); else zlog_info ("[Event] BGP connection IP address %s is Idle state", inet_sutop (&su, buf)); } close (bgp_sock); return -1; } /* In case of peer is EBGP, we should set TTL for this connection. */ if (peer_sort (peer1) == BGP_PEER_EBGP) sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl); if (! bgp) bgp = peer1->bgp; /* Make dummy peer until read Open packet. */ if (BGP_DEBUG (events, EVENTS)) zlog_info ("[Event] Make dummy peer structure until read Open packet"); { char buf[SU_ADDRSTRLEN + 1]; peer = peer_create_accept (bgp); SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER); peer->su = su; peer->fd = bgp_sock; peer->status = Active; peer->local_id = peer1->local_id; /* Make peer's address string. */ sockunion2str (&su, buf, SU_ADDRSTRLEN); peer->host = strdup (buf); } BGP_EVENT_ADD (peer, TCP_connection_open); return 0; }
s32 ws__getBgpNeighborInfo(WS_ENV * ws_env,s32 afi, s32 safi, s32 nstart, s32 nsize, struct BgpNeighborInfosRespone * ret ) { s8 temp[SU_ADDRSTRLEN]; s32 count = 0 , i = 0; s32 sum = 0 ; s32 max = 0; struct BgpNeighborInfos * out = NULL; web_bgp_neighbor_info_t * info = (void*)buff; if( socket_api_write(WEB_BGP_APICMD_GET_NBR,NULL,0) < 0 ) return ws_send_soap_error(ws_env,"send command error!"); do{ count = socket_api_read(WEB_BGP_APICMD_GET_NBR,buff,SOCKET_API_BUFFER_SIZE); if( count <= 0 ) { break; } if( max < sum + count ) { void * tmp = ws_malloc(ws_env,(sum + count)*sizeof(struct BgpNeighborInfos)); if( out != NULL ) { memcpy(tmp,out,sum * sizeof(struct BgpNeighborInfos)); ws_free(ws_env,out); } out = tmp ; max = sum + count ; } for(i=0;i<count;i++) { out[sum].addr = ws_strdup(ws_env, sockunion2str(&(info[i].su), temp, SU_ADDRSTRLEN) ) ; out[sum].asid = info[i].as ; out[sum].hop = info[i].hop ; out[sum].af = info[i].af ; out[sum].uptype=info[i].upsrc_type; out[sum].upvalue=ws_strdup(ws_env, (s8*)info[i].upsrc); out[sum].passvalue=ws_strdup(ws_env, (s8*)info[i].passwd); out[sum].passtype=(info[i].passwd[0]==0)?0:1; out[sum].defaultorg=info[i].default_org; out[sum].nexthopchg=info[i].nexthop_chg; out[sum].noroute =info[i].no_route ; out[sum].allows =info[i].allows_in ; out[sum].allowsmax =info[i].allows_in_max; out[sum].localas =(info[i].localas>0)?1:0 ; out[sum].localasvalue = info[i].localas ; out[sum].keepalive = info[i].keepalive ; out[sum].holdtime = info[i].holdtime ; out[sum].modtime = (out[sum].keepalive||out[sum].holdtime)?1:0 ; out[sum].commnum = info[i].comm_num ; out[sum].commstr = ws_strdup(ws_env, (s8*)info[i].comm_str) ; out[sum].comm = (out[sum].commnum||strlen(out[sum].commstr))?1:0 ; sum++; } }while( ! socket_api_check_flag(SOCKET_API_FLAG_LASTONE) ); ret->ret.sum = sum ; ret->ret.__ptrres = out ; ret->ret.__size = sum ; ret->ret.res_USCOREcount = sum ; return WS_OK; }
/* Accept bgp connection. */ static int bgp_accept (struct thread *thread) { int bgp_sock; //socket used for BGP connection int accept_sock; union sockunion su; struct bgp_listener *listener = THREAD_ARG(thread); struct peer *peer; struct peer *peer1; char buf[SU_ADDRSTRLEN]; /* Register accept thread to accept connections from a client */ accept_sock = THREAD_FD (thread); if (accept_sock < 0) { zlog_err ("accept_sock is nevative value %d", accept_sock); return -1; } /*creating a new reading thread*/ listener->thread = thread_add_read (master, bgp_accept, listener, accept_sock); /* -------------------------------------------------- * - BGP ACCEPT - * -------------------------------------------------- * */ printf("\n BGP ACCEPT: About to initialise SSL \n"); ssl_init(); //initialise the library, method, contact of ssl session, returns nothing printf("\n BGP ACCEPT: About to do socket call \n"); bgp_sock = sockunion_accept (accept_sock, &su); SSL_accept(BGPoTLS->ssl); if (bgp_sock < 0) { zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno)); return -1; } set_nonblocking (bgp_sock); if (BGP_DEBUG (events, EVENTS)) zlog_debug("[Event] BGP connection from host %s", inet_sutop (&su, buf)); /* Check remote IP address */ peer1 = peer_lookup (NULL, &su); if (! peer1 || peer1->status == Idle) { if (BGP_DEBUG (events, EVENTS)) { if (! peer1) zlog_debug ("[Event] BGP connection IP address %s is not configured", inet_sutop (&su, buf)); else zlog_debug ("[Event] BGP connection IP address %s is Idle state", inet_sutop (&su, buf)); } close (bgp_sock); return -1; } /* In case of peer is EBGP, we should set TTL for this connection. */ if (peer1->sort == BGP_PEER_EBGP) { sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl); if (peer1->gtsm_hops) sockopt_minttl (peer1->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer1->gtsm_hops); } /* Make dummy peer until read Open packet. */ if (BGP_DEBUG (events, EVENTS)) zlog_debug ("[Event] Make dummy peer structure until read Open packet"); { char buf[SU_ADDRSTRLEN]; peer = peer_create_accept (peer1->bgp); SET_FLAG (peer->sflags, PEER_STATUS_ACCEPT_PEER); peer->su = su; peer->fd = bgp_sock; peer->status = Active; peer->local_id = peer1->local_id; peer->v_holdtime = peer1->v_holdtime; peer->v_keepalive = peer1->v_keepalive; /* Make peer's address string. */ sockunion2str (&su, buf, SU_ADDRSTRLEN); peer->host = XSTRDUP (MTYPE_BGP_PEER_HOST, buf); } BGP_EVENT_ADD (peer, TCP_connection_open); return 0; }