summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author刘畅 <[email protected]>2024-02-28 08:35:39 +0000
committer刘畅 <[email protected]>2024-02-28 08:35:39 +0000
commit2a4f87a098b07e42e3178814f20dae28f06b1b83 (patch)
tree4a499cd92885deb4043c3517da35ff4338338652
parent5cdde1b9d74d053ddf5e505dc3a39f2154fb3d1e (diff)
parente01a9248bd9d0d79f74e6590cd19f36e7e4d09df (diff)
Merge branch 'bugfix_ip_header_checksum' into 'rel'v3.1.23
fix ip header checksum See merge request tango/shaping-engine!80
-rw-r--r--common/src/raw_packet.cpp51
-rw-r--r--common/test/gtest_raw_packet.cpp3
-rw-r--r--conf/table_info.json2
-rw-r--r--shaping/include/shaper_aqm.h4
-rw-r--r--shaping/src/shaper_aqm.cpp19
-rw-r--r--shaping/test/gtest_shaper_aqm.cpp18
6 files changed, 55 insertions, 42 deletions
diff --git a/common/src/raw_packet.cpp b/common/src/raw_packet.cpp
index 83dd0f0..3b6dad3 100644
--- a/common/src/raw_packet.cpp
+++ b/common/src/raw_packet.cpp
@@ -1,6 +1,7 @@
#include <assert.h>
#include <errno.h>
#include <linux/if_ether.h>
+#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
@@ -1059,30 +1060,29 @@ static const void *parse_mpls(struct raw_pkt_parser *handler, const void *data,
}
}
-static unsigned short ip_checksum(struct iphdr *iph) {
- // 初始化检验和为0
- unsigned short checksum = 0;
- // 将IP头的指针转换为无符号短整型的指针
- unsigned short *p = (unsigned short *)iph;
- // 计算IP头的长度,单位为字节
- int len = iph->ihl * 4;
- // 逐个累加IP头的每个16位字段
- while (len > 1) {
- checksum += *p++;
- len -= 2;
- }
- // 如果IP头的长度为奇数,将最后一个字节视为高8位,低8位补0,再累加
- if (len == 1) {
- checksum += *(unsigned char *)p << 8;
- }
- // 将检验和的高16位和低16位相加,直到没有进位
- while (checksum >> 16) {
- checksum = (checksum & 0xFFFF) + (checksum >> 16);
- }
- // 将检验和取反
- checksum = ~checksum;
- // 返回检验和
- return checksum;
+static unsigned short ip_header_checksum_calculate(struct iphdr *iph)
+{
+ unsigned short *buffer = (unsigned short *)iph;
+ unsigned int length = iph->ihl * 4;
+ unsigned int sum = 0;
+
+ while (length > 1)
+ {
+ sum += *buffer++;
+ length -= 2;
+ }
+
+ if (length > 0)
+ {
+ sum += ((*buffer) & htons(0xFF00));
+ }
+
+ while (sum >> 16)
+ {
+ sum = (sum & 0xFFFF) + (sum >> 16);
+ }
+
+ return ~sum;
}
void raw_packet_set_dscp(struct ethhdr *eth_hdr, uint8_t dscp)
@@ -1092,7 +1092,8 @@ void raw_packet_set_dscp(struct ethhdr *eth_hdr, uint8_t dscp)
struct iphdr *ip_hdr = (struct iphdr *)(eth_hdr + 1);
ip_hdr->tos = (ip_hdr->tos & 0x03) | (dscp << 2);
//recalculate checksum
- ip_hdr->check = ip_checksum(ip_hdr);
+ ip_hdr->check = 0;
+ ip_hdr->check = ip_header_checksum_calculate(ip_hdr);
}
else if (eth_hdr->h_proto == htons(ETH_P_IPV6))
{
diff --git a/common/test/gtest_raw_packet.cpp b/common/test/gtest_raw_packet.cpp
index 02422da..69d752f 100644
--- a/common/test/gtest_raw_packet.cpp
+++ b/common/test/gtest_raw_packet.cpp
@@ -1391,6 +1391,9 @@ TEST(RAW_PACKET, SET_IPV4_DSCP_VALUE)
raw_packet_set_dscp(eth, 40);//40 is CS5
dscp_value = ip->tos >> 2;
EXPECT_EQ(dscp_value, 40);
+
+ EXPECT_EQ(htons(ip->check), 0x7fb3);
+
pcap_close(handle);
}
diff --git a/conf/table_info.json b/conf/table_info.json
index 90aebc8..b99eca1 100644
--- a/conf/table_info.json
+++ b/conf/table_info.json
@@ -15,7 +15,7 @@
"table_id": 1,
"table_name": "TRAFFIC_SHAPING_PROFILE",
"table_type": "plugin",
- "valid_column": 8,
+ "valid_column": 7,
"custom": {
"gc_timeout_s":2,
"key": 1,
diff --git a/shaping/include/shaper_aqm.h b/shaping/include/shaper_aqm.h
index 2955c3a..8575076 100644
--- a/shaping/include/shaper_aqm.h
+++ b/shaping/include/shaper_aqm.h
@@ -35,5 +35,5 @@ struct shaper_aqm_codel_para {
};
int shaper_aqm_need_drop(struct shaping_profile_info *profile, struct shaping_packet_wrapper *pkt_wrapper, struct timespec *curr_time, unsigned long long latency_us);
-int shaper_aqm_blue_need_drop(struct shaper_aqm_blue_para *para, int curr_queue_len);
-int shaper_aqm_codel_need_drop(struct shaper_aqm_codel_para *para, unsigned long long curr_time_ms, unsigned long long latency_ms); \ No newline at end of file
+int shaper_aqm_blue_need_drop(int profile_id, struct shaper_aqm_blue_para *para, int curr_queue_len);
+int shaper_aqm_codel_need_drop(int profile_id, struct shaper_aqm_codel_para *para, unsigned long long curr_time_ms, unsigned long long latency_ms); \ No newline at end of file
diff --git a/shaping/src/shaper_aqm.cpp b/shaping/src/shaper_aqm.cpp
index e06bf7e..96d3e8b 100644
--- a/shaping/src/shaper_aqm.cpp
+++ b/shaping/src/shaper_aqm.cpp
@@ -1,10 +1,11 @@
#include <math.h>
#include <time.h>
+#include "log.h"
#include "shaper.h"
#include "shaper_aqm.h"
thread_local unsigned int seed = 0;
-int shaper_aqm_blue_need_drop(struct shaper_aqm_blue_para *para, int curr_queue_len)
+int shaper_aqm_blue_need_drop(int profile_id, struct shaper_aqm_blue_para *para, int curr_queue_len)
{
time_t curr_time;
@@ -15,6 +16,8 @@ int shaper_aqm_blue_need_drop(struct shaper_aqm_blue_para *para, int curr_queue_
} else if (curr_queue_len == 0) {
para->probability = (para->probability - BLUE_DECREMENT) >= 0 ? (para->probability - BLUE_DECREMENT) : 0;
}
+
+ LOG_INFO("%s: profile id: %d blue probability update to %d", LOG_TAG_SHAPING, profile_id, para->probability);
}
if (rand_r(&seed) % BLUE_PROBABILITY_MAX < para->probability) {
@@ -24,10 +27,14 @@ int shaper_aqm_blue_need_drop(struct shaper_aqm_blue_para *para, int curr_queue_
return 0;
}
-int shaper_aqm_codel_need_drop(struct shaper_aqm_codel_para *para, unsigned long long curr_time_ms, unsigned long long latency_ms)
+int shaper_aqm_codel_need_drop(int profile_id, struct shaper_aqm_codel_para *para, unsigned long long curr_time_ms, unsigned long long latency_ms)
{
if (latency_ms < CODEL_MAX_LATENCY) {
- para->state = CODEL_STATE_NORMAL;
+ if (para->state != CODEL_STATE_NORMAL) {
+ para->state = CODEL_STATE_NORMAL;
+ LOG_INFO("%s: profile id: %d codel enter state CODEL_STATE_NORMAL", LOG_TAG_SHAPING, profile_id);
+ }
+
return 0;
}
@@ -36,6 +43,7 @@ int shaper_aqm_codel_need_drop(struct shaper_aqm_codel_para *para, unsigned long
case CODEL_STATE_NORMAL:
para->start_drop_time_ms = curr_time_ms + CODEL_DROP_INTERVAL;
para->state = CODEL_STATE_DROPPING_TIMER;
+ LOG_INFO("%s: profile id: %d codel enter state CODEL_STATE_DROPPING_TIMER", LOG_TAG_SHAPING, profile_id);
break;
case CODEL_STATE_DROPPING_TIMER:
if (curr_time_ms >= para->start_drop_time_ms) {
@@ -43,6 +51,7 @@ int shaper_aqm_codel_need_drop(struct shaper_aqm_codel_para *para, unsigned long
para->drop_count = 1;
para->next_drop_time_ms = curr_time_ms + CODEL_DROP_INTERVAL / sqrt(para->drop_count);
ret = 1;
+ LOG_INFO("%s: profile id: %d codel enter state CODEL_STATE_DROPPING_PHASE", LOG_TAG_SHAPING, profile_id);
}
break;
case CODEL_STATE_DROPPING_PHASE:
@@ -102,11 +111,11 @@ int shaper_aqm_need_drop(struct shaping_profile_info *profile, struct shaping_pa
switch (profile->hash_node->aqm_type) {
case AQM_TYPE_BLUE:
- ret = shaper_aqm_blue_need_drop(&profile->hash_node->aqm_blue_para, profile->hash_node->queue_len[profile->priority]);
+ ret = shaper_aqm_blue_need_drop(profile->id, &profile->hash_node->aqm_blue_para, profile->hash_node->queue_len[profile->priority]);
break;
case AQM_TYPE_CODEL:
curr_time_ms = curr_time->tv_sec * MILLI_SECONDS_PER_SEC + curr_time->tv_nsec / NANO_SECONDS_PER_MILLI_SEC;
- ret = shaper_aqm_codel_need_drop(&profile->hash_node->aqm_codel_para, curr_time_ms, latency_us / 1000);
+ ret = shaper_aqm_codel_need_drop(profile->id, &profile->hash_node->aqm_codel_para, curr_time_ms, latency_us / 1000);
break;
default:
break;
diff --git a/shaping/test/gtest_shaper_aqm.cpp b/shaping/test/gtest_shaper_aqm.cpp
index 92bab10..6acb1f3 100644
--- a/shaping/test/gtest_shaper_aqm.cpp
+++ b/shaping/test/gtest_shaper_aqm.cpp
@@ -13,7 +13,7 @@ TEST(aqm_bule, need_drop)
para.probability = 0;
for (int i = 0; i < 10000; i++) {
- if (shaper_aqm_blue_need_drop(&para, BLUE_QUEUE_LEN_MAX + 1)) {
+ if (shaper_aqm_blue_need_drop(0, &para, BLUE_QUEUE_LEN_MAX + 1)) {
drop_cnt++;
}
}
@@ -24,7 +24,7 @@ TEST(aqm_bule, need_drop)
EXPECT_LT(drop_cnt, 1100);
sleep(3);
- shaper_aqm_blue_need_drop(&para, 0);
+ shaper_aqm_blue_need_drop(0, &para, 0);
EXPECT_EQ(para.probability, BLUE_INCREMENT - BLUE_DECREMENT);
}
@@ -37,7 +37,7 @@ TEST(aqm_blue, no_drop)
para.probability = 0;
for (int i = 0; i < 10000; i++) {
- if (shaper_aqm_blue_need_drop(&para, BLUE_QUEUE_LEN_MAX - 1)) {
+ if (shaper_aqm_blue_need_drop(0, &para, BLUE_QUEUE_LEN_MAX - 1)) {
drop_cnt++;
}
}
@@ -46,7 +46,7 @@ TEST(aqm_blue, no_drop)
EXPECT_EQ(drop_cnt, 0);
sleep(3);
- shaper_aqm_blue_need_drop(&para, BLUE_QUEUE_LEN_MAX - 1);
+ shaper_aqm_blue_need_drop(0, &para, BLUE_QUEUE_LEN_MAX - 1);
EXPECT_EQ(para.probability, 0);
}
@@ -57,23 +57,23 @@ TEST(aqm_codel, need_drop)
memset(&para, 0, sizeof(para));
- shaper_aqm_codel_need_drop(&para, curr_time_ms, CODEL_MAX_LATENCY + 1);
+ shaper_aqm_codel_need_drop(0, &para, curr_time_ms, CODEL_MAX_LATENCY + 1);
EXPECT_EQ(para.state, CODEL_STATE_DROPPING_TIMER);
EXPECT_EQ(para.start_drop_time_ms, curr_time_ms + CODEL_DROP_INTERVAL);
curr_time_ms = para.start_drop_time_ms + 1;
- shaper_aqm_codel_need_drop(&para, curr_time_ms, CODEL_MAX_LATENCY + 1);
+ shaper_aqm_codel_need_drop(0, &para, curr_time_ms, CODEL_MAX_LATENCY + 1);
EXPECT_EQ(para.state, CODEL_STATE_DROPPING_PHASE);
EXPECT_EQ(para.drop_count, 1);
EXPECT_EQ(para.next_drop_time_ms, int(curr_time_ms + CODEL_DROP_INTERVAL / sqrt(para.drop_count)));
curr_time_ms = para.next_drop_time_ms + 1;
- shaper_aqm_codel_need_drop(&para, curr_time_ms, CODEL_MAX_LATENCY + 1);
+ shaper_aqm_codel_need_drop(0, &para, curr_time_ms, CODEL_MAX_LATENCY + 1);
EXPECT_EQ(para.state, CODEL_STATE_DROPPING_PHASE);
EXPECT_EQ(para.drop_count, 2);
EXPECT_EQ(para.next_drop_time_ms, int(curr_time_ms + CODEL_DROP_INTERVAL / sqrt(para.drop_count)));
- shaper_aqm_codel_need_drop(&para, curr_time_ms, CODEL_MAX_LATENCY - 1);
+ shaper_aqm_codel_need_drop(0, &para, curr_time_ms, CODEL_MAX_LATENCY - 1);
EXPECT_EQ(para.state, CODEL_STATE_NORMAL);
}
@@ -84,7 +84,7 @@ TEST(aqm_codel, no_drop)
memset(&para, 0, sizeof(para));
- shaper_aqm_codel_need_drop(&para, curr_time_ms, CODEL_MAX_LATENCY - 1);
+ shaper_aqm_codel_need_drop(0, &para, curr_time_ms, CODEL_MAX_LATENCY - 1);
EXPECT_EQ(para.state, CODEL_STATE_NORMAL);
EXPECT_EQ(para.drop_count, 0);
}