lagopus_result_t session_bind(lagopus_session_t s, struct addrunion *saddr, uint16_t sport) { int ret; char addr[256]; char port[16]; if (s == NULL || saddr == NULL || sport == 0) { lagopus_msg_warning("session is null.\n"); return LAGOPUS_RESULT_ANY_FAILURES; } inet_ntop(saddr->family, &saddr->addr4, addr, sizeof(addr)); snprintf(port, sizeof(port), "%d", sport); ret = bind_default(s, addr, port); if (ret < 0) { lagopus_msg_warning("bind_default error.\n"); return LAGOPUS_RESULT_POSIX_API_ERROR; } if (s->session_type & SESSION_PASSIVE) { ret = listen(s->sock, SOMAXCONN); if (ret < 0) { return LAGOPUS_RESULT_POSIX_API_ERROR; } } return LAGOPUS_RESULT_OK; }
lagopus_result_t ofp_port_status_handle(struct port_status *port_status, uint64_t dpid) { lagopus_result_t ret; struct pbuf *send_pbuf = NULL; if (port_status != NULL) { /* PortStatus. */ ret = ofp_port_status_create(port_status, &send_pbuf); if (ret == LAGOPUS_RESULT_OK) { ret = ofp_role_channel_write(send_pbuf, dpid, OFPT_PORT_STATUS, port_status->ofp_port_status.reason); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("Socket write error (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED : ofp_port_status_create (%s).\n", lagopus_error_get_string(ret)); } /* free. */ if (send_pbuf != NULL) { pbuf_free(send_pbuf); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
bool ofp_header_version_check(struct channel *channel, struct ofp_header *header) { bool ret = false; uint8_t bridge_ofp_version; uint64_t dpid; if (channel != NULL && header != NULL) { dpid = channel_dpid_get(channel); ret = dpmgr_bridge_ofp_version_get(dpid, &bridge_ofp_version); if (ret == LAGOPUS_RESULT_OK) { if (bridge_ofp_version == header->version) { ret = true; } else { lagopus_msg_warning("Unsupported ofp version : %"PRIu8".\n", header->version); ret = false; } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); ret = false; } } else { lagopus_msg_warning("Arg is NULL.\n"); ret = false; } return ret; }
void lagopus_callout_finalize_handler(void) { if (s_is_handler_inited == true) { lagopus_result_t r = LAGOPUS_RESULT_ANY_FAILURES; /* * Stop the main loop first then shutdown/wait/destroy the callout * stage/workers. */ if (likely((r = s_stop_callout_main_loop()) == LAGOPUS_RESULT_OK)) { if (likely(s_n_workers > 0)) { r = s_finish_callout_stage(CALLOUT_STAGE_SHUTDOWN_TIMEOUT); if (unlikely(r != LAGOPUS_RESULT_OK)) { lagopus_perror(r); lagopus_msg_warning("failed to stop the callout stage so the " "callout queues still remain.\n"); goto done; } } s_destroy_all_queued_timed_tasks(); (void)lagopus_bbq_clear(&s_urgent_tsk_q, true); (void)lagopus_bbq_clear(&s_idle_tsk_q, true); } else { lagopus_perror(r); lagopus_msg_warning("failed to stop the callout scheduler main loop.\n"); } done: s_is_handler_inited = false; } }
static lagopus_result_t s_parse_bucket_list(struct pbuf *pbuf, struct bucket_list *bucket_list, struct ofp_error *error) { lagopus_result_t res = LAGOPUS_RESULT_OK; if (TAILQ_EMPTY(bucket_list) == true && pbuf_plen_get(pbuf) == 0) { res = LAGOPUS_RESULT_OK; /* bucket_list is empty */ } else { /* decode buckets. */ while (pbuf_plen_get(pbuf) > 0) { res = ofp_bucket_parse(pbuf, bucket_list, error); if (res != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED : ofp_bucket_parse (%s).\n", lagopus_error_get_string(res)); break; } } /* check plen. */ if (res == LAGOPUS_RESULT_OK && pbuf_plen_get(pbuf) > 0) { lagopus_msg_warning("packet decode failed. (size over).\n"); ofp_error_set(error, OFPET_GROUP_MOD_FAILED, OFPGMFC_BAD_BUCKET); res = LAGOPUS_RESULT_OFP_ERROR; } } return res; }
/* Experimenter packet receive. */ lagopus_result_t ofp_experimenter_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct pbuf *send_pbuf = NULL; struct ofp_experimenter_header exper_req; if (channel != NULL && pbuf != NULL && xid_header != NULL) { /* Parse packet. */ ret = ofp_experimenter_header_decode(pbuf, &exper_req); if (ret == LAGOPUS_RESULT_OK) { /* Experimenter request reply. */ ret = ofp_experimenter_reply_create(channel, &send_pbuf, xid_header, &exper_req); if (ret == LAGOPUS_RESULT_OK) { channel_send_packet(channel, send_pbuf); ret = LAGOPUS_RESULT_OK; } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); ret = LAGOPUS_RESULT_OFP_ERROR; } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
/* Send PacketIn packet. */ lagopus_result_t ofp_packet_in_handle(struct packet_in *packet_in, uint64_t dpid) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct pbuf *send_pbuf = NULL; if (packet_in != NULL && packet_in->data != NULL) { /* PacketIn. */ ret = ofp_packet_in_create(packet_in, &send_pbuf); if (ret == LAGOPUS_RESULT_OK) { ret = ofp_role_channel_write(send_pbuf, dpid, OFPT_PACKET_IN, packet_in->ofp_packet_in.reason); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("Socket write error (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("Arg is NULL.\n"); ret = LAGOPUS_RESULT_INVALID_ARGS; } /* free. */ if (send_pbuf != NULL) { pbuf_free(send_pbuf); } return ret; }
lagopus_result_t session_connect_check(lagopus_session_t s) { int ret0, value; lagopus_result_t ret1; socklen_t len = sizeof(value); if (s == NULL) { lagopus_msg_warning("session is null.\n"); return LAGOPUS_RESULT_ANY_FAILURES; } ret0 = getsockopt(s->sock, SOL_SOCKET, SO_ERROR, (void *)&value, &len); if (ret0 < 0) { lagopus_msg_warning("getsockopt error %d.\n", errno); return LAGOPUS_RESULT_ANY_FAILURES; } else if (value != 0) { lagopus_msg_warning("getsockopt value error %d.\n", value); return LAGOPUS_RESULT_SOCKET_ERROR; } if (s->connect_check) { ret1 = s->connect_check(s); } else { ret1 = LAGOPUS_RESULT_OK; } return ret1; }
bool ofp_role_generation_id_check(uint64_t dpid, uint32_t role, uint64_t generation_id) { uint64_t gen; lagopus_result_t ret; if (role != OFPCR_ROLE_MASTER && role != OFPCR_ROLE_SLAVE) { /* do not care */ return true; } ret = channel_mgr_generation_id_get(dpid, &gen); if (ret == LAGOPUS_RESULT_OK && distance(generation_id, gen) < 0) { lagopus_msg_warning("generation_id was already updated(old: %ld, new:%ld).\n", gen, generation_id); return false; } else if (ret != LAGOPUS_RESULT_OK && ret != LAGOPUS_RESULT_NOT_DEFINED) { return false; } ret = channel_mgr_generation_id_set(dpid, generation_id); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("generation_id update failed(old: %ld, new:%ld).\n", gen, generation_id); return false; } return true; }
/* Group mod received. */ lagopus_result_t ofp_group_mod_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES; uint64_t dpid; struct ofp_group_mod group_mod; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { /* Parse group_mod header. */ res = ofp_group_mod_decode(pbuf, &(group_mod)); if (res == LAGOPUS_RESULT_OK) { /* check type */ res = s_group_type_check(group_mod.type, error); if (res == LAGOPUS_RESULT_OK) { /* exec group_mod command. */ dpid = channel_dpid_get(channel); switch (group_mod.command) { case OFPGC_ADD: res = s_ofpgc_add(pbuf, dpid, &group_mod, error); break; case OFPGC_MODIFY: res = s_ofpgc_modify(pbuf, dpid, &group_mod, error); break; case OFPGC_DELETE: res = s_ofpgc_delete(pbuf, dpid, &group_mod, error); break; default: lagopus_msg_warning("unknown group_mod command.\n"); ofp_error_set(error, OFPET_GROUP_MOD_FAILED, OFPGMFC_BAD_COMMAND); res = LAGOPUS_RESULT_OFP_ERROR; break; } } if (res != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } else { lagopus_msg_warning("group_mod decode error (%s)\n", lagopus_error_get_string(res)); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); res = LAGOPUS_RESULT_OFP_ERROR; } } else { /* params are NULL */ res = LAGOPUS_RESULT_INVALID_ARGS; } return res; }
lagopus_result_t ofp_get_async_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct pbuf *send_pbuf = NULL; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { ret = pbuf_plen_check(pbuf, xid_header->length); if (ret == LAGOPUS_RESULT_OK) { /* Parse packet. */ ret = ofp_header_handle(channel, pbuf, error); if (ret == LAGOPUS_RESULT_OK) { /* dump trace. */ get_async_request_trace(xid_header); /* Reply send.*/ ret = ofp_get_async_reply_create(channel, &send_pbuf, xid_header); if (ret == LAGOPUS_RESULT_OK) { channel_send_packet(channel, send_pbuf); } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); ret = LAGOPUS_RESULT_OFP_ERROR; } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } } else { lagopus_msg_warning("bad length.\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); ret = LAGOPUS_RESULT_OFP_ERROR; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
/* Port mod received. */ lagopus_result_t ofp_port_mod_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES; uint64_t dpid; struct ofp_port_mod port_mod; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { /* Parse port_mod header. */ res = ofp_port_mod_decode(pbuf, &(port_mod)); if (res != LAGOPUS_RESULT_OK) { lagopus_msg_warning("port_mod decode error.\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); res = LAGOPUS_RESULT_OFP_ERROR; } else if (pbuf_plen_get(pbuf) > 0) { lagopus_msg_warning("packet decode failed. (size over).\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); res = LAGOPUS_RESULT_OFP_ERROR; } else { /* decode success */ /* dump trace. */ port_mod_trace(&port_mod); /* check config. */ res = ofp_port_config_check(port_mod.config, error); if (res == LAGOPUS_RESULT_OK) { /* check mask. */ res = ofp_port_config_check(port_mod.mask, error); if (res == LAGOPUS_RESULT_OK) { /* check advertise. */ res = ofp_port_features_check(port_mod.advertise, error); if (res == LAGOPUS_RESULT_OK) { dpid = channel_dpid_get(channel); /* call API */ res = ofp_port_mod_modify(dpid, &port_mod, error); if (res != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(res)); } } } } } } else { res = LAGOPUS_RESULT_INVALID_ARGS; } return res; }
lagopus_result_t ofp_header_packet_set(struct channel *channel, struct pbuf *pbuf) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; uint16_t cur_length; pbuf_info_t cur_pbuf_info; pbuf_info_t update_pbuf_info; struct ofp_header header; if (channel != NULL && pbuf != NULL) { /* Store current pbuf info. */ pbuf_info_store(pbuf, &cur_pbuf_info); ret = pbuf_length_get(pbuf, &cur_length); if (ret == LAGOPUS_RESULT_OK) { /* Update pbuf info for ofp_header_decode_sneak. */ pbuf_getp_set(&update_pbuf_info, pbuf_data_get(pbuf)); pbuf_putp_set(&update_pbuf_info, pbuf_data_get(pbuf) + sizeof(struct ofp_header)); pbuf_plen_set(&update_pbuf_info, sizeof(struct ofp_header)); pbuf_info_load(pbuf, &update_pbuf_info); ret = ofp_header_decode_sneak(pbuf, &header); if (ret == LAGOPUS_RESULT_OK) { /* Update pbuf info for ofp_header_create. */ pbuf_reset(pbuf); pbuf_plen_set(pbuf, (size_t) cur_length); ret = ofp_header_create(channel, header.type, NULL, &header, pbuf); if (ret == LAGOPUS_RESULT_OK) { /* Load pbuf info. */ pbuf_info_load(pbuf, &cur_pbuf_info); } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { return LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
STATIC lagopus_result_t ofp_role_reply_create(struct channel *channel, struct pbuf **pbuf, struct ofp_header *xid_header, struct ofp_role_request *role_request) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; /* reply is ofp_role_request structure. */ struct ofp_role_request role_reply; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && role_request != NULL) { /* alloc */ *pbuf = channel_pbuf_list_get(channel, sizeof(struct ofp_role_request)); if (*pbuf != NULL) { pbuf_plen_set(*pbuf, sizeof(struct ofp_role_request)); /* Fill in header. */ ofp_header_set(&role_reply.header, channel_version_get(channel), OFPT_ROLE_REPLY, (uint16_t) pbuf_plen_get(*pbuf), xid_header->xid); role_reply.role = role_request->role; memset(role_reply.pad, 0, sizeof(role_request->pad)); role_reply.generation_id = role_request->generation_id; /* Encode message. */ ret = ofp_role_request_encode(*pbuf, &role_reply); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) { channel_pbuf_list_unget(channel, *pbuf); *pbuf = NULL; } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
lagopus_result_t ofp_meter_features_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t res = LAGOPUS_RESULT_ANY_FAILURES; uint64_t dpid; struct ofp_meter_features ofp_meter_features; struct pbuf_list *send_pbuf_list = NULL; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { if (pbuf_plen_equal_check(pbuf, 0) == LAGOPUS_RESULT_OK) { /* get datas */ memset(&ofp_meter_features, 0, sizeof(ofp_meter_features)); dpid = channel_dpid_get(channel); res = ofp_meter_features_get(dpid, &ofp_meter_features, error); if (res == LAGOPUS_RESULT_OK) { /* create desc reply. */ res = ofp_meter_features_reply_create(channel, &send_pbuf_list, &ofp_meter_features, xid_header); if (res == LAGOPUS_RESULT_OK) { /* send desc reply */ res = channel_send_packet_list(channel, send_pbuf_list); if (res != LAGOPUS_RESULT_OK) { lagopus_msg_warning("Socket write error (%s).\n", lagopus_error_get_string(res)); } } else { lagopus_msg_warning("reply creation failed, (%s).\n", lagopus_error_get_string(res)); } /* free. */ if (send_pbuf_list != NULL) { pbuf_list_free(send_pbuf_list); } } } else { lagopus_msg_warning("over packet length.\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); res = LAGOPUS_RESULT_OFP_ERROR; } } else { res = LAGOPUS_RESULT_INVALID_ARGS; } return res; }
/* Group Features Request packet receive. */ lagopus_result_t ofp_group_features_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t ret; uint64_t dpid; struct ofp_group_features group_features; struct pbuf_list *pbuf_list = NULL; if (channel != NULL && pbuf != NULL && xid_header != NULL && error != NULL) { if (pbuf_plen_equal_check(pbuf, 0) == LAGOPUS_RESULT_OK) { dpid = channel_dpid_get(channel); ret = ofp_group_features_get(dpid, &group_features, error); if (ret == LAGOPUS_RESULT_OK) { ret = ofp_group_features_reply_create(channel, &pbuf_list, &group_features, xid_header); if (ret == LAGOPUS_RESULT_OK) { /* write packets. */ ret = channel_send_packet_list(channel, pbuf_list); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("Can't write\n"); } } else { lagopus_msg_warning("FAILED (%s)\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s)\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("over packet length.\n"); ofp_error_set(error, OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); ret = LAGOPUS_RESULT_OFP_ERROR; } /* free. */ if (pbuf_list != NULL) { pbuf_list_free(pbuf_list); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
static lagopus_result_t ofp_write_channel(struct channel *channel, struct pbuf *pbuf) { lagopus_result_t ret = LAGOPUS_RESULT_OK; struct pbuf *send_pbuf = NULL; uint16_t len = 0; if (channel != NULL && pbuf != NULL) { ret = pbuf_length_get(pbuf, &len); if (ret == LAGOPUS_RESULT_OK) { send_pbuf = channel_pbuf_list_get(channel, (size_t) len); if (send_pbuf != NULL) { /* Copy pbuf. */ ret = pbuf_copy(send_pbuf, pbuf); if (ret == LAGOPUS_RESULT_OK) { ret = ofp_header_packet_set(channel, send_pbuf); if (ret == LAGOPUS_RESULT_OK) { channel_send_packet(channel, send_pbuf); ret = LAGOPUS_RESULT_OK; } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
static int check_cert_chain(const SSL *ssl) { int ret = -1; char *issuer = NULL, *subject = NULL; X509 *peer = NULL; if (SSL_get_verify_result(ssl) != X509_V_OK) { lagopus_msg_warning("SSL_get_verify_result() failed.\n"); return -1; } peer = SSL_get_peer_certificate(ssl); if (peer == NULL) { lagopus_msg_warning("SSL_get_peer_certificate() failed.\n"); return -1; } issuer = X509_NAME_oneline(X509_get_issuer_name(peer), NULL, 0); if (issuer == NULL) { lagopus_msg_warning("no memory, get_issuer_name failed.\n"); ret = -1; goto done; } subject = X509_NAME_oneline(X509_get_subject_name(peer), NULL, 0); if (issuer == NULL) { lagopus_msg_warning("no memory, get_subject_name failed.\n"); ret = -1; goto done; } if (check_certificates != NULL) { if (check_certificates(issuer, subject) == LAGOPUS_RESULT_OK) { ret = 0; } else { ret = -1; } lagopus_msg_info("issuer:[%s], subject:[%s] ret: %d\n", issuer, subject, ret); } else { lagopus_msg_warning("check_certificates function is null.\n"); } done: free(issuer); free(subject); X509_free(peer); return ret; }
static int bind_default(lagopus_session_t s, const char *host, const char *port) { int ret; int sock = -1; char service[NI_MAXSERV]; struct addrinfo hints = {0,0,0,0,0,NULL,NULL,NULL}, *res = NULL; snprintf(service, sizeof(service), "%s", port); lagopus_msg_debug(10, "host:%s, service:%s\n", host, service); hints.ai_family = s->family; hints.ai_socktype = s->type; ret = getaddrinfo(host, service, &hints, &res); if (ret != 0) { lagopus_msg_warning("getaddrinfo error %s.\n", gai_strerror(ret)); freeaddrinfo(res); return -1; } sock = socket_create(res->ai_family, res->ai_socktype, res->ai_protocol, s->session_type & SESSION_ACTIVE ? true : false); if (sock < 0) { freeaddrinfo(res); return -1; } if (s->session_type & SESSION_PASSIVE) { const int on = 1; ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (ret < 0) { lagopus_msg_warning("setsockopt error %s.\n", strerror(errno)); freeaddrinfo(res); close(sock); return ret; } } ret = bind(sock, res->ai_addr, res->ai_addrlen); if (ret < 0 && errno != EINPROGRESS) { lagopus_msg_warning("connect error %s.\n", strerror(errno)); freeaddrinfo(res); close(sock); return ret; } s->sock = sock; freeaddrinfo(res); return ret; }
STATIC lagopus_result_t ofp_get_async_reply_create(struct channel *channel, struct pbuf **pbuf, struct ofp_header *xid_header) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct ofp_async_config async_config; /* check params */ if (channel != NULL && pbuf != NULL && xid_header != NULL) { /* alloc */ *pbuf = channel_pbuf_list_get(channel, sizeof(struct ofp_async_config)); if (*pbuf != NULL) { pbuf_plen_set(*pbuf, sizeof(struct ofp_async_config)); /* Copy packet_in_mask, port_status_mask, flow_removed_mask. */ channel_role_mask_get(channel, &async_config); /* Fill in header. */ ofp_header_set(&async_config.header, channel_version_get(channel), OFPT_GET_ASYNC_REPLY, (uint16_t) pbuf_plen_get(*pbuf), xid_header->xid); /* Encode message. */ ret = ofp_async_config_encode(*pbuf, &async_config); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED : ofp_async_config_encode (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) { channel_pbuf_list_unget(channel, *pbuf); *pbuf = NULL; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
lagopus_result_t session_accept(lagopus_session_t s1, lagopus_session_t *s2) { int sock; struct sockaddr_storage ss = {0,0,{0}}; socklen_t ss_len = sizeof(ss); session_type_t t; lagopus_result_t ret; sock = accept(s1->sock, (struct sockaddr *) &ss, &ss_len); if (sock < 0) { lagopus_msg_warning("accept error.\n"); return LAGOPUS_RESULT_POSIX_API_ERROR; } t = ((s1->session_type & (unsigned int) ~(SESSION_PASSIVE|SESSION_ACTIVE)) | SESSION_ACCEPTED); ret = session_create(t, s2); if (*s2 == NULL) { close(sock); return ret; } (*s2)->sock = sock; if (s1->accept != NULL) { return s1->accept(s1, s2); } return LAGOPUS_RESULT_OK; }
/* Features Request packet receive. */ lagopus_result_t ofp_features_request_handle(struct channel *channel, struct pbuf *pbuf, struct ofp_header *xid_header, struct ofp_error *error) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; struct pbuf *send_pbuf = NULL; /* Parse packet. */ ret = ofp_header_handle(channel, pbuf, error); if (ret == LAGOPUS_RESULT_OK) { /* Features request reply. */ ret = ofp_features_reply_create(channel, &send_pbuf, xid_header); if (ret == LAGOPUS_RESULT_OK) { features_request_trace(xid_header); channel_send_packet(channel, send_pbuf); ret = LAGOPUS_RESULT_OK; } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } if (ret != LAGOPUS_RESULT_OK && send_pbuf != NULL) { channel_pbuf_list_unget(channel, send_pbuf); } return ret; }
static inline lagopus_result_t bridgeq_mgr_map_to_array(void) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (bridgeq_table != NULL) { bridgeq_mgr_lock(); n_bridgeqs = 0; if (lagopus_hashmap_size(&bridgeq_table) != 0) { /* NOTE: * hashmap_iterate() is very slow. */ ret = lagopus_hashmap_iterate(&bridgeq_table, iter_to_array, NULL); } else { ret = LAGOPUS_RESULT_OK; } bridgeq_mgr_unlock(); } else { ret = LAGOPUS_RESULT_INVALID_OBJECT; lagopus_msg_warning("bridgeq_table is NULL.\n"); } return ret; }
lagopus_result_t ofp_bridgeq_mgr_bridgeqs_to_array(struct ofp_bridgeq *brqs[], uint64_t *count, const size_t max_size) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; uint64_t i; if (brqs != NULL && count != NULL && max_size <= MAX_BRIDGES) { if (bridgeq_table != NULL) { bridgeq_mgr_lock(); for (i = 0; i < n_bridgeqs; i++) { brqs[i] = bridgeqs[i]; /* inclement reference counter */ ofp_bridgeq_refs_get(bridgeqs[i]); } *count = n_bridgeqs; bridgeq_mgr_unlock(); ret = LAGOPUS_RESULT_OK; } else { ret = LAGOPUS_RESULT_INVALID_OBJECT; lagopus_msg_warning("bridgeq_table is NULL.\n"); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
static inline bool s_check_get_thread_id(lagopus_thread_t *thd_ptr, lagopus_result_t require_ret) { bool result = false; lagopus_result_t ret; pthread_t tid; int i; for (i = 0; i < GET_TID_RETRY; i++) { ret = lagopus_thread_get_pthread_id(thd_ptr, &tid); if (ret == require_ret) { break; } } if (ret == require_ret) { if (ret == LAGOPUS_RESULT_OK) { TEST_ASSERT_NOT_EQUAL(tid, LAGOPUS_INVALID_THREAD); } result = true; } else { if (require_ret == LAGOPUS_RESULT_OK && ret == LAGOPUS_RESULT_ALREADY_HALTED) { lagopus_msg_warning( "test requires LAGOPUS_RESULT_OK, but result is LAGOPUS_ALREADY_HALTED. " "Modify value of WAIT_NSEC and MAIN_SLEEP_USEC of thread_test.c, please try again.\n"); result = true; } else { lagopus_perror(ret); TEST_FAIL_MESSAGE("get_thread_id failed"); result = false; } } return result; }
static lagopus_result_t connect_check_tls(struct session *s) { long res = -1; X509 *peer = NULL; lagopus_result_t ret = 0; lagopus_msg_debug(10, "connect check in\n"); if (IS_CTX_NULL(s)) { lagopus_msg_warning("session ctx is null.\n"); return LAGOPUS_RESULT_INVALID_ARGS; } if (IS_TLS_NOT_INIT(s) == false) { res = SSL_get_verify_result(GET_TLS_CTX(s)->ssl); peer = SSL_get_peer_certificate(GET_TLS_CTX(s)->ssl); } if (res != X509_V_OK || peer == NULL || GET_TLS_CTX(s)->verified == false) { ret = connect_tls(s, NULL, NULL); } lagopus_msg_debug(10, "connect check out ret:%d\n", (int) ret); return ret; }
/* header only packet. */ lagopus_result_t ofp_header_create(struct channel *channel, uint8_t type, struct ofp_header *xid_header, struct ofp_header *header, struct pbuf *pbuf) { lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; uint32_t xid; if (channel != NULL && header != NULL && pbuf != NULL) { if (xid_header != NULL) { xid = xid_header->xid; } else { xid = channel_xid_get(channel); } ofp_header_set(header, channel_version_get(channel), type, (uint16_t) pbuf_plen_get(pbuf), xid); ret = ofp_header_encode(pbuf, header); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
/** * Delete route information notified from netlink. */ void rib_notifier_ipv4_route_delete(struct in_addr *dest, int prefixlen, struct in_addr *gate, int ifindex) { struct rib *rib; lagopus_result_t rv; struct notification_entry *entry = NULL; rv = ifinfo_rib_get(ifindex, &rib); if (rv == LAGOPUS_RESULT_OK && rib != NULL) { entry = rib_create_notification_entry(NOTIFICATION_TYPE_ROUTE, NOTIFICATION_ACTION_TYPE_DEL); if (entry) { /* add notification entry to queue. */ entry->route.ifindex = ifindex; entry->route.dest = *dest; entry->route.gate = *gate; entry->route.scope = 0; entry->route.prefixlen = prefixlen; rv = rib_add_notification_entry(rib, entry); } else { lagopus_msg_warning("create notification entry failed\n"); } } return; }
/* Send switch features reply. */ STATIC lagopus_result_t ofp_features_reply_create(struct channel *channel, struct pbuf **pbuf, struct ofp_header *xid_header) { struct ofp_switch_features features; lagopus_result_t ret = LAGOPUS_RESULT_ANY_FAILURES; if (channel != NULL && pbuf != NULL && xid_header != NULL) { /* alloc */ *pbuf = channel_pbuf_list_get(channel, sizeof(struct ofp_switch_features)); if (*pbuf != NULL) { pbuf_plen_set(*pbuf, sizeof(struct ofp_switch_features)); ret = features_reply_features_get(channel, &features); if (ret == LAGOPUS_RESULT_OK) { /* Fill in header. */ ofp_header_set(&features.header, channel_version_get(channel), OFPT_FEATURES_REPLY, (uint16_t) pbuf_plen_get(*pbuf), xid_header->xid); /* Encode message. */ ret = ofp_switch_features_encode(*pbuf, &features); if (ret != LAGOPUS_RESULT_OK) { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("FAILED (%s).\n", lagopus_error_get_string(ret)); } } else { lagopus_msg_warning("Can't allocate pbuf.\n"); ret = LAGOPUS_RESULT_NO_MEMORY; } if (ret != LAGOPUS_RESULT_OK && *pbuf != NULL) { channel_pbuf_list_unget(channel, *pbuf); *pbuf = NULL; } } else { ret = LAGOPUS_RESULT_INVALID_ARGS; } return ret; }
/** * Add ipv4 addr information notified from netlink. */ void rib_notifier_ipv4_addr_add(int ifindex, struct in_addr *addr, int prefixlen, struct in_addr *broad, char *label) { lagopus_result_t rv; struct ifinfo_entry *entry; struct ifinfo_entry *dentry; uint8_t hwaddr[UPDATER_ETH_LEN]; struct bridge *bridge; struct notification_entry *nentry = NULL; addr_ipv4_log("add", ifindex, addr, prefixlen, broad, label); /* new ifinfo entry to registered to ifinfo_hashmap. */ entry = calloc(1, sizeof(struct ifinfo_entry)); if (entry == NULL) { lagopus_msg_warning("no memory.\n"); return; } memset(entry, 0, sizeof(struct ifinfo_entry)); memcpy(entry->ifname, label, strlen(label)); if (dp_tapio_interface_info_get(label, hwaddr, &bridge) != LAGOPUS_RESULT_OK) { lagopus_msg_warning("get interface info failed.\n"); ifinfo_entry_free(entry); return; } memcpy(entry->hwaddr, hwaddr, UPDATER_ETH_LEN); entry->rib = &(bridge->rib); dentry = entry; lagopus_hashmap_add(&ifinfo_hashmap, (void *)ifindex, (void **)&dentry, true); /* create and set notification entry. */ nentry = rib_create_notification_entry(NOTIFICATION_TYPE_IFADDR, NOTIFICATION_ACTION_TYPE_ADD); if (nentry) { /* add notification entry to queue. */ nentry->ifaddr.ifindex = ifindex; rv = rib_add_notification_entry(&bridge->rib, nentry); } else { lagopus_msg_warning("create notification entry failed\n"); ifinfo_entry_free(entry); } return; }