Merge "DscpPolicy Optimize skb store bytes"
This commit is contained in:
@@ -36,8 +36,6 @@
|
|||||||
#define ECN_MASK 3
|
#define ECN_MASK 3
|
||||||
#define IP4_OFFSET(field, header) (header + offsetof(struct iphdr, field))
|
#define IP4_OFFSET(field, header) (header + offsetof(struct iphdr, field))
|
||||||
#define UPDATE_TOS(dscp, tos) (dscp << 2) | (tos & ECN_MASK)
|
#define UPDATE_TOS(dscp, tos) (dscp << 2) | (tos & ECN_MASK)
|
||||||
#define UPDATE_PRIORITY(dscp) ((dscp >> 2) + 0x60)
|
|
||||||
#define UPDATE_FLOW_LABEL(dscp, flow_lbl) ((dscp & 0xf) << 6) + (flow_lbl >> 6)
|
|
||||||
|
|
||||||
DEFINE_BPF_MAP_GRW(switch_comp_map, ARRAY, int, uint64_t, 1, AID_SYSTEM)
|
DEFINE_BPF_MAP_GRW(switch_comp_map, ARRAY, int, uint64_t, 1, AID_SYSTEM)
|
||||||
|
|
||||||
@@ -80,9 +78,8 @@ static inline __always_inline void match_policy(struct __sk_buff* skb, bool ipv4
|
|||||||
uint8_t protocol = 0; // TODO: Use are reserved value? Or int (-1) and cast to uint below?
|
uint8_t protocol = 0; // TODO: Use are reserved value? Or int (-1) and cast to uint below?
|
||||||
struct in6_addr src_ip = {};
|
struct in6_addr src_ip = {};
|
||||||
struct in6_addr dst_ip = {};
|
struct in6_addr dst_ip = {};
|
||||||
uint8_t tos = 0; // Only used for IPv4
|
uint8_t tos = 0; // Only used for IPv4
|
||||||
uint8_t priority = 0; // Only used for IPv6
|
uint32_t old_first_u32 = 0; // Only used for IPv6
|
||||||
uint8_t flow_lbl = 0; // Only used for IPv6
|
|
||||||
if (ipv4) {
|
if (ipv4) {
|
||||||
const struct iphdr* const iph = (void*)(eth + 1);
|
const struct iphdr* const iph = (void*)(eth + 1);
|
||||||
hdr_size = l2_header_size + sizeof(struct iphdr);
|
hdr_size = l2_header_size + sizeof(struct iphdr);
|
||||||
@@ -115,8 +112,7 @@ static inline __always_inline void match_policy(struct __sk_buff* skb, bool ipv4
|
|||||||
src_ip = ip6h->saddr;
|
src_ip = ip6h->saddr;
|
||||||
dst_ip = ip6h->daddr;
|
dst_ip = ip6h->daddr;
|
||||||
protocol = ip6h->nexthdr;
|
protocol = ip6h->nexthdr;
|
||||||
priority = ip6h->priority;
|
old_first_u32 = *(uint32_t*)ip6h;
|
||||||
flow_lbl = ip6h->flow_lbl[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
@@ -164,10 +160,10 @@ static inline __always_inline void match_policy(struct __sk_buff* skb, bool ipv4
|
|||||||
sizeof(uint16_t));
|
sizeof(uint16_t));
|
||||||
bpf_skb_store_bytes(skb, IP4_OFFSET(tos, l2_header_size), &newTos, sizeof(newTos), 0);
|
bpf_skb_store_bytes(skb, IP4_OFFSET(tos, l2_header_size), &newTos, sizeof(newTos), 0);
|
||||||
} else {
|
} else {
|
||||||
uint8_t new_priority = UPDATE_PRIORITY(existing_rule->dscp_val);
|
uint32_t new_first_u32 =
|
||||||
uint8_t new_flow_label = UPDATE_FLOW_LABEL(existing_rule->dscp_val, flow_lbl);
|
htonl(ntohl(old_first_u32) & 0xF03FFFFF | (existing_rule->dscp_val << 22));
|
||||||
bpf_skb_store_bytes(skb, 0 + l2_header_size, &new_priority, sizeof(uint8_t), 0);
|
bpf_skb_store_bytes(skb, l2_header_size, &new_first_u32, sizeof(uint32_t),
|
||||||
bpf_skb_store_bytes(skb, 1 + l2_header_size, &new_flow_label, sizeof(uint8_t), 0);
|
BPF_F_RECOMPUTE_CSUM);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -227,10 +223,7 @@ static inline __always_inline void match_policy(struct __sk_buff* skb, bool ipv4
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t new_tos = 0; // Can 0 be used as default forwarding value?
|
|
||||||
uint8_t new_dscp = 0;
|
uint8_t new_dscp = 0;
|
||||||
uint8_t new_priority = 0;
|
|
||||||
uint8_t new_flow_lbl = 0;
|
|
||||||
if (best_score > 0) {
|
if (best_score > 0) {
|
||||||
DscpPolicy* policy;
|
DscpPolicy* policy;
|
||||||
if (ipv4) {
|
if (ipv4) {
|
||||||
@@ -241,12 +234,6 @@ static inline __always_inline void match_policy(struct __sk_buff* skb, bool ipv4
|
|||||||
|
|
||||||
if (policy) {
|
if (policy) {
|
||||||
new_dscp = policy->dscp_val;
|
new_dscp = policy->dscp_val;
|
||||||
if (ipv4) {
|
|
||||||
new_tos = UPDATE_TOS(new_dscp, tos);
|
|
||||||
} else {
|
|
||||||
new_priority = UPDATE_PRIORITY(new_dscp);
|
|
||||||
new_flow_lbl = UPDATE_FLOW_LABEL(new_dscp, flow_lbl);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
@@ -277,18 +264,20 @@ static inline __always_inline void match_policy(struct __sk_buff* skb, bool ipv4
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Need to store bytes after updating map or program will not load.
|
// Need to store bytes after updating map or program will not load.
|
||||||
if (ipv4 && new_tos != (tos & 252)) {
|
if (ipv4) {
|
||||||
|
uint8_t new_tos = UPDATE_TOS(new_dscp, tos);
|
||||||
bpf_l3_csum_replace(skb, IP4_OFFSET(check, l2_header_size), htons(tos), htons(new_tos), 2);
|
bpf_l3_csum_replace(skb, IP4_OFFSET(check, l2_header_size), htons(tos), htons(new_tos), 2);
|
||||||
bpf_skb_store_bytes(skb, IP4_OFFSET(tos, l2_header_size), &new_tos, sizeof(new_tos), 0);
|
bpf_skb_store_bytes(skb, IP4_OFFSET(tos, l2_header_size), &new_tos, sizeof(new_tos), 0);
|
||||||
} else if (!ipv4 && (new_priority != priority || new_flow_lbl != flow_lbl)) {
|
} else {
|
||||||
bpf_skb_store_bytes(skb, l2_header_size, &new_priority, sizeof(new_priority), 0);
|
uint32_t new_first_u32 = htonl(ntohl(old_first_u32) & 0xF03FFFFF | (new_dscp << 22));
|
||||||
bpf_skb_store_bytes(skb, l2_header_size + 1, &new_flow_lbl, sizeof(new_flow_lbl), 0);
|
bpf_skb_store_bytes(skb, l2_header_size, &new_first_u32, sizeof(uint32_t),
|
||||||
|
BPF_F_RECOMPUTE_CSUM);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_BPF_PROG_KVER("schedcls/set_dscp_ether", AID_ROOT, AID_SYSTEM,
|
DEFINE_BPF_PROG_KVER("schedcls/set_dscp_ether", AID_ROOT, AID_SYSTEM, schedcls_set_dscp_ether,
|
||||||
schedcls_set_dscp_ether, KVER(5, 15, 0))
|
KVER(5, 15, 0))
|
||||||
(struct __sk_buff* skb) {
|
(struct __sk_buff* skb) {
|
||||||
if (skb->pkt_type != PACKET_HOST) return TC_ACT_PIPE;
|
if (skb->pkt_type != PACKET_HOST) return TC_ACT_PIPE;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user