diff --git a/services/netmanagernative/bpf/include/netfirewall/netfirewall_domain.h b/services/netmanagernative/bpf/include/netfirewall/netfirewall_domain.h index bd0aa46f4d6bd1044e0936854af4d8a265ffe5b7..f0bdc4f8d1d32dc12b8e897b4efea7707bcd51c8 100755 --- a/services/netmanagernative/bpf/include/netfirewall/netfirewall_domain.h +++ b/services/netmanagernative/bpf/include/netfirewall/netfirewall_domain.h @@ -230,7 +230,7 @@ static __always_inline enum sk_action match_dns_query(struct __sk_buff *skb) __u8 protocol = 0; __u32 l4_nhoff = 0; - if (skb->family == AF_INET) { + if (is_ipv4_format_skb(skb)) { struct iphdr iph = { 0 }; bpf_skb_load_bytes(skb, 0, &iph, sizeof(struct iphdr)); protocol = iph.protocol; diff --git a/services/netmanagernative/bpf/include/netfirewall/netfirewall_match.h b/services/netmanagernative/bpf/include/netfirewall/netfirewall_match.h index 373528ed632235720dcc8ecf7fe7ba6f8506f883..d88ce31aa3fd3f1c5e94fc98457374aec86642c4 100755 --- a/services/netmanagernative/bpf/include/netfirewall/netfirewall_match.h +++ b/services/netmanagernative/bpf/include/netfirewall/netfirewall_match.h @@ -92,7 +92,7 @@ static __always_inline bool get_match_tuple(struct __sk_buff *skb, struct match_ __u32 l3_nhoff = get_l3_nhoff(skb); __u32 l4_nhoff = get_l4_nhoff(skb); __u8 protocol = 0; - if (skb->family == AF_INET) { + if (is_ipv4_format_skb(skb)) { load_l3_v4_addrs(skb, l3_nhoff, &(tuple->ipv4.saddr), &(tuple->ipv4.daddr)); } else { load_l3_v6_addrs(skb, l3_nhoff, &(tuple->ipv6.saddr), &(tuple->ipv6.daddr)); diff --git a/services/netmanagernative/bpf/include/netfirewall/netfirewall_utils.h b/services/netmanagernative/bpf/include/netfirewall/netfirewall_utils.h index d2df45ba96ac80e8fdfa91b8520ff6659bb39226..ed504d4b6624ec8733a4f09c71b16f1d457bb7ab 100755 --- a/services/netmanagernative/bpf/include/netfirewall/netfirewall_utils.h +++ b/services/netmanagernative/bpf/include/netfirewall/netfirewall_utils.h @@ -36,6 +36,8 @@ #define TCP_FLAGS_OFFSET 12 #define TCP_FLAGS_SIZE 2 +#define VERSION_IPV4 4 +#define VERSION_OFFSET 4 #define L3_NHOFF 0 #define L4_NHOFF(ipv4) (L3_NHOFF + ((ipv4) ? sizeof(struct iphdr) : sizeof(struct ipv6hdr))) @@ -49,6 +51,28 @@ union tcp_flags { __u32 value; }; +/** + * @brief judget given skb is ipv4 packet, even if its family is AF_INET6 + * + * @param skb struct __sk_buff + * @return true if it is ipv4 packet, otherwise false + */ +static __always_inline bool is_ipv4_format_skb(struct __sk_buff *skb) +{ + if (!skb) { + return false; + } + if (skb->family == AF_INET) { + return true; + } + if (skb->family == AF_INET6) { + uint8_t version = { 0 }; + bpf_skb_load_bytes(skb, 0, &version, sizeof(uint8_t)); + return ((version >> VERSION_OFFSET) == VERSION_IPV4); + } + return false; +} + /** * @brief judget given skb is a layler 4 protocol or not * @@ -59,13 +83,12 @@ union tcp_flags { */ static __always_inline bool is_l4_protocol(struct __sk_buff *skb, __u32 l3_nhoff, __u8 protocol) { - if (skb->family == AF_INET) { + if (is_ipv4_format_skb(skb)) { struct iphdr iph = { 0 }; bpf_skb_load_bytes(skb, l3_nhoff, &iph, sizeof(struct iphdr)); return iph.protocol == protocol; - } - if (skb->family == AF_INET6) { + } else if (skb->family == AF_INET6) { struct ipv6hdr ip6h = { 0 }; bpf_skb_load_bytes(skb, l3_nhoff, &ip6h, sizeof(struct ipv6hdr)); @@ -96,7 +119,7 @@ static __always_inline __u32 get_l3_nhoff(struct __sk_buff *skb) */ static __always_inline __u32 get_l4_nhoff(struct __sk_buff *skb) { - return L4_NHOFF(skb->family == AF_INET); + return L4_NHOFF(is_ipv4_format_skb(skb)); } /** @@ -122,7 +145,7 @@ static __always_inline int load_tcp_flags(struct __sk_buff *skb, __u32 l4_nhoff, */ static __always_inline bool load_l4_protocol(const struct __sk_buff *skb, __u32 l3_nhoff, __u8 *protocol) { - if (skb->family == AF_INET) { + if (is_ipv4_format_skb(skb)) { struct iphdr iph = { 0 }; bpf_skb_load_bytes(skb, l3_nhoff, &iph, sizeof(struct iphdr));