diff --git a/common/include/kni_utils.h b/common/include/kni_utils.h index a104bb0..46f4b15 100644 --- a/common/include/kni_utils.h +++ b/common/include/kni_utils.h @@ -95,6 +95,7 @@ enum kni_field{ KNI_FIELD_IPV6HDR_PARSE_FAIL, KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC, KNI_FIELD_KEEPALIVE_REPLAY_ADD_FAIL, + KNI_FIELD_EXCEED_MTU, }; struct kni_field_stat_handle{ diff --git a/common/src/kni_utils.cpp b/common/src/kni_utils.cpp index 05eb301..a9f9f22 100644 --- a/common/src/kni_utils.cpp +++ b/common/src/kni_utils.cpp @@ -306,7 +306,7 @@ MESA_htable_handle kni_create_htable(const char *profile, const char *section, v return htable; } -char* kni_ipv4_errmsg_get(int _errno){ +char* kni_ipv4_errmsg_get(enum kni_ipv4hdr_parse_error _errno){ switch(_errno){ case KNI_IPV4HDR_PARSE_ERROR_NULL_PACKET: return (char*)"null packet"; @@ -315,7 +315,7 @@ char* kni_ipv4_errmsg_get(int _errno){ } } -char* kni_ipv6_errmsg_get(int _errno){ +char* kni_ipv6_errmsg_get(enum kni_ipv6hdr_parse_error _errno){ switch(_errno){ case KNI_IPV6HDR_PARSE_ERROR_NULL_PACKET: return (char*)"null packet"; diff --git a/entry/src/kni_entry.cpp b/entry/src/kni_entry.cpp index 1e3d4e1..b58b1b0 100644 --- a/entry/src/kni_entry.cpp +++ b/entry/src/kni_entry.cpp @@ -40,6 +40,7 @@ enum stream_error{ STREAM_ERROR_IPV4HDR_PARSE_FAIL = -7, STREAM_ERROR_IPV6HDR_PARSE_FAIL = -8, STREAM_ERROR_DUP_STREAM = -9, + STREAM_ERROR_EXCEED_MTU = -10, }; struct http_project{ @@ -180,11 +181,13 @@ static char* stream_errmsg_get(enum stream_error _errno){ case STREAM_ERROR_INVALID_ACTION: return (char*)"invalid aciton"; case STREAM_ERROR_NO_DATA: - return (char*)""; + return (char*)"no data"; case STREAM_ERROR_IPV4HDR_PARSE_FAIL: return (char*)"ipv4 header parse fail"; case STREAM_ERROR_IPV6HDR_PARSE_FAIL: return (char*)"ipv6 header parse fail"; + case STREAM_ERROR_EXCEED_MTU: + return (char*)"exceed mtu(1500)"; default: return (char*)"unknown error"; } @@ -652,7 +655,7 @@ static char* add_cmsg_to_packet(struct pme_info *pmeinfo, struct pkt_info *pktin return new_pkt; } -static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_t raw_len, int thread_seq, int tfe_id){ +static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_t raw_len, int thread_seq, int tfe_id, addr_type_t addr_type){ void *logger = g_kni_handle->local_logger; marsio_buff_t *tx_buffs[BURST_MAX]; struct mr_vdev *dev_eth_handler = handle->tfe_instance_list[tfe_id]->dev_eth_handler; @@ -673,7 +676,12 @@ static int send_to_tfe(struct kni_marsio_handle *handle, char *raw_data, uint16_ struct ethhdr *ether_hdr = (struct ethhdr*)dst_data; memcpy(ether_hdr->h_dest, dst_mac, sizeof(ether_hdr->h_dest)); memcpy(ether_hdr->h_source, src_mac, sizeof(ether_hdr->h_source)); - ether_hdr->h_proto = htons(ETH_P_IP); + if(addr_type == ADDR_TYPE_IPV6){ + ether_hdr->h_proto = htons(ETH_P_IPV6); + } + else{ + ether_hdr->h_proto = htons(ETH_P_IP); + } memcpy((char*)dst_data + sizeof(*ether_hdr), raw_data, raw_len); } marsio_send_burst(dev_eth_sendpath, thread_seq, tx_buffs, nr_send); @@ -809,10 +817,13 @@ static int first_data_intercept(const struct streaminfo *stream, struct pme_info //action = KNI_ACTION_INTERCEPT, sendto tfe int len = 0; char *buf = add_cmsg_to_packet(pmeinfo, pktinfo, &len); - ret = send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq, pmeinfo->tfe_id); + ret = send_to_tfe(g_kni_handle->marsio_handle, buf, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type); if(ret < 0){ KNI_LOG_ERROR(logger, "Failed at send first packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); } + else{ + KNI_LOG_DEBUG(logger, "Succeed at send first packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); + } FREE(&buf); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_PKT], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_INTCP_STM], 0, FS_OP_ADD, 1); @@ -848,7 +859,7 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein ipv4_hdr = (struct iphdr*)a_packet; len = ntohs(ipv4_hdr->tot_len); } - ret = send_to_tfe(g_kni_handle->marsio_handle, (char*)a_packet, len, thread_seq, pmeinfo->tfe_id); + ret = send_to_tfe(g_kni_handle->marsio_handle, (char*)a_packet, len, thread_seq, pmeinfo->tfe_id, pmeinfo->addr_type); if(ret < 0){ KNI_LOG_ERROR(logger, "Failed at send continue packet to tfe%d, stream traceid is %s", pmeinfo->tfe_id, pmeinfo->stream_traceid); } @@ -867,23 +878,26 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein if(ret < 0){ return APP_STATE_FAWPKT | APP_STATE_DROPME; } + //first data > 1500, bypass and dropme + if(pktinfo.ip_totlen > KNI_DEFAULT_MTU){ + pmeinfo->error = STREAM_ERROR_EXCEED_MTU; + KNI_LOG_ERROR(logger, "first data packet exceed MTU(1500), bypass and dropme"); + FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_EXCEED_MTU], 0, FS_OP_ADD, 1); + return APP_STATE_FAWPKT | APP_STATE_DROPME; + } // syn/ack if(pktinfo.tcphdr->syn && pktinfo.tcphdr->ack){ pmeinfo->server_window = pktinfo.tcphdr->window; pmeinfo->server_tcpopt = kni_get_tcpopt(pktinfo.tcphdr, pktinfo.tcphdr_len); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); return APP_STATE_FAWPKT | APP_STATE_GIVEME; } //no data, maybe ack if(pktinfo.data_len <= 0){ - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); return APP_STATE_FAWPKT | APP_STATE_GIVEME; } //not double dir, bypass and dropme if(stream->dir != DIR_DOUBLE){ KNI_LOG_INFO(logger, "dir is %d, bypass, stream addr is %s", stream->dir, stream_addr); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_SINGLE_DIR; return APP_STATE_FAWPKT | APP_STATE_DROPME; } @@ -896,8 +910,6 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein case KNI_PROTOCOL_UNKNOWN: KNI_LOG_INFO(logger, "Failed at protocol_identify, bypass and dropme, stream addr is %s\n", pmeinfo->protocol, stream_addr); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_UNKNOWN_STM], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_PROTOCOL_UNKNOWN; return APP_STATE_FAWPKT | APP_STATE_DROPME; @@ -917,15 +929,13 @@ static char data_opstate(const struct streaminfo *stream, struct pme_info *pmein thread_seq, &(pmeinfo->policy_id), &(pmeinfo->maat_hit)); //policy scan log char *action_str = kni_maat_action_trans(pmeinfo->action); - KNI_LOG_DEBUG(logger, "intercept_policy_scan: %s, %s, policy_id = %d, action = %d(%s), maat_hit = %d", - stream_addr, protocol_identify_res.domain, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->maat_hit); + KNI_LOG_DEBUG(logger, "intercept_policy_scan: %s, %s, policy_id = %d, action = %d(%s), maat_hit = %d, stream traceid is %s", + stream_addr, protocol_identify_res.domain, pmeinfo->policy_id, pmeinfo->action, action_str, pmeinfo->maat_hit, pmeinfo->stream_traceid); //receive client hello, but no syn/ack, bypass and dropme if(pmeinfo->client_tcpopt == NULL || pmeinfo->server_tcpopt == NULL){ KNI_LOG_ERROR(logger, "Failed at intercept, %s, %s, stream traceid is %s", pmeinfo->client_tcpopt == NULL ? "no syn" : "have syn", pmeinfo->server_tcpopt == NULL ? "no syn/ack" : "have syn/ack", pmeinfo->stream_traceid); FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_NO_SA_EXP], 0, FS_OP_ADD, 1); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_PKT], 0, FS_OP_ADD, 1); - //FS_operate(g_kni_fs_handle->handle, g_kni_fs_handle->fields[KNI_FIELD_BYP_STM], 0, FS_OP_ADD, 1); pmeinfo->error = STREAM_ERROR_NO_SYN_ACK; return APP_STATE_FAWPKT | APP_STATE_DROPME; } @@ -961,10 +971,10 @@ static char close_opstate(const struct streaminfo *stream, struct pme_info *pmei strnlen(pmeinfo->stream_traceid, sizeof(pmeinfo->stream_traceid))); return APP_STATE_DROPPKT | APP_STATE_DROPME; case KNI_ACTION_BYPASS: - KNI_LOG_DEBUG(logger, "set tfe_release = 1, stream_trace_id is %s", pmeinfo->stream_traceid); + KNI_LOG_DEBUG(logger, "action is bypass, set tfe_release = 1, stream_trace_id is %s", pmeinfo->stream_traceid); pmeinfo->tfe_release = 1; return APP_STATE_FAWPKT | APP_STATE_DROPME; - //stream has only syn, ack. not data. do not send to tfe + //stream has only syn, ack. no data. default: char *action_str = kni_maat_action_trans(pmeinfo->action); pmeinfo->error = STREAM_ERROR_NO_DATA; @@ -1178,7 +1188,7 @@ static long keepalive_replay_search_cb(void *data, const uchar *key, uint size, replay_packet_iphdr->saddr, replay_packet_iphdr->daddr); } //send to tfe: thread_seq = g_iThreadNum - int ret = send_to_tfe(marsio_handle, replay_packet, tot_len, g_iThreadNum + thread_seq, tfe_id); + int ret = send_to_tfe(marsio_handle, replay_packet, tot_len, g_iThreadNum + thread_seq, tfe_id, args->addr_type); if(ret < 0){ KNI_LOG_ERROR(logger, "Failed at send keepalive replay packet to tfe"); } @@ -1616,6 +1626,7 @@ static struct kni_field_stat_handle * fs_init(const char *profile){ fs_handle->fields[KNI_FIELD_IPV6HDR_PARSE_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "ipv6hdr_parse_fail"); fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_FAIL] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kaReplay_add_fail"); fs_handle->fields[KNI_FIELD_KEEPALIVE_REPLAY_ADD_SUCC] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "kaReplay_add_succ"); + fs_handle->fields[KNI_FIELD_EXCEED_MTU] = FS_register(handle, FS_STYLE_FIELD, FS_CALC_CURRENT, "exceed_mtu"); fs_handle->handle = handle; FS_start(handle); return fs_handle;