Skip to content

Commit c5db324

Browse files
authored
Merge pull request #69 from xdp-project/tutorial31-improve-parsing
Change parse_ethhdr() to return network-byte-order This fix #59. One reason for not using bpf_ntohs() call on packet data (eth->h_proto) is that users of the API can instead do compares against constants e.g. VLAN check bpf_htons(ETH_P_8021Q), which will allow compiler to do this compile time (instead of runtime). This is also changed, because in several places code access packet-headers eth->h_proto directly (which is in network-byte-order) and at the same time the code also use parse_ethhdr(),which before returned in host-byte-order. Thus, I this makes the code more consistent. E.g. before you could not use the result from parse_ethhdr() as input to proto_is_vlan().
2 parents 94471ee + 87c1bc8 commit c5db324

8 files changed

Lines changed: 20 additions & 18 deletions

File tree

common/parsing_helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static __always_inline int parse_ethhdr(struct hdr_cursor *nh, void *data_end,
106106
}
107107

108108
nh->pos = vlh;
109-
return bpf_ntohs(h_proto);
109+
return h_proto; /* network-byte-order */
110110
}
111111

112112
static __always_inline int parse_ip6hdr(struct hdr_cursor *nh,

packet-solutions/xdp_prog_kern_02.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ int xdp_patch_ports_func(struct xdp_md *ctx)
3737
goto out;
3838
}
3939

40-
if (eth_type == ETH_P_IP) {
40+
if (eth_type == bpf_htons(ETH_P_IP)) {
4141
ip_type = parse_iphdr(&nh, data_end, &iphdr);
42-
} else if (eth_type == ETH_P_IPV6) {
42+
} else if (eth_type == bpf_htons(ETH_P_IPV6)) {
4343
ip_type = parse_ip6hdr(&nh, data_end, &ipv6hdr);
4444
} else {
4545
goto out;

packet-solutions/xdp_prog_kern_03.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ int xdp_icmp_echo_func(struct xdp_md *ctx)
7676

7777
/* Parse Ethernet and IP/IPv6 headers */
7878
eth_type = parse_ethhdr(&nh, data_end, &eth);
79-
if (eth_type == ETH_P_IP) {
79+
if (eth_type == bpf_htons(ETH_P_IP)) {
8080
ip_type = parse_iphdr(&nh, data_end, &iphdr);
8181
if (ip_type != IPPROTO_ICMP)
8282
goto out;
83-
} else if (eth_type == ETH_P_IPV6) {
83+
} else if (eth_type == bpf_htons(ETH_P_IPV6)) {
8484
ip_type = parse_ip6hdr(&nh, data_end, &ipv6hdr);
8585
if (ip_type != IPPROTO_ICMPV6)
8686
goto out;
@@ -95,11 +95,12 @@ int xdp_icmp_echo_func(struct xdp_md *ctx)
9595
* the rest of the structure.
9696
*/
9797
icmp_type = parse_icmphdr_common(&nh, data_end, &icmphdr);
98-
if (eth_type == ETH_P_IP && icmp_type == ICMP_ECHO) {
98+
if (eth_type == bpf_htons(ETH_P_IP) && icmp_type == ICMP_ECHO) {
9999
/* Swap IP source and destination */
100100
swap_src_dst_ipv4(iphdr);
101101
echo_reply = ICMP_ECHOREPLY;
102-
} else if (eth_type == ETH_P_IPV6 && icmp_type == ICMPV6_ECHO_REQUEST) {
102+
} else if (eth_type == bpf_htons(ETH_P_IPV6)
103+
&& icmp_type == ICMPV6_ECHO_REQUEST) {
103104
/* Swap IPv6 source and destination */
104105
swap_src_dst_ipv6(ipv6hdr);
105106
echo_reply = ICMPV6_ECHO_REPLY;

packet-solutions/xdp_vlan01_kern.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ static __always_inline int parse_ethhdr(struct hdr_cursor *nh, void *data_end,
7575
}
7676

7777
nh->pos = vlh;
78-
return bpf_ntohs(h_proto);
78+
return h_proto; /* network-byte-order */
7979
}
8080

8181
SEC("xdp_vlan01")

packet-solutions/xdp_vlan02_kern.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static __always_inline int __parse_ethhdr_vlan(struct hdr_cursor *nh,
5757
}
5858

5959
nh->pos = vlh;
60-
return bpf_ntohs(h_proto);
60+
return h_proto; /* network-byte-order */
6161
}
6262

6363
SEC("xdp_vlan02")
@@ -102,7 +102,7 @@ int xdp_vlan_02(struct xdp_md *ctx)
102102
#if 0
103103
int ip_type;
104104
struct iphdr *iphdr;
105-
if (eth_type == ETH_P_IP) {
105+
if (eth_type == bpf_htons(ETH_P_IP)) {
106106
ip_type = parse_iphdr(&nh, data_end, &iphdr);
107107
if (eth_type < 0)
108108
return XDP_ABORTED;

packet01-parsing/xdp_prog_kern.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ static __always_inline int parse_ethhdr(struct hdr_cursor *nh,
4242
nh->pos += hdrsize;
4343
*ethhdr = eth;
4444

45-
return bpf_ntohs(eth->h_proto);
45+
return eth->h_proto; /* network-byte-order */
4646
}
4747

4848
/* Assignment 2: Implement and use this */
@@ -84,7 +84,7 @@ int xdp_parser_func(struct xdp_md *ctx)
8484
* header type in the packet correct?), and bounds checking.
8585
*/
8686
nh_type = parse_ethhdr(&nh, data_end, &eth);
87-
if (nh_type != ETH_P_IPV6)
87+
if (nh_type != bpf_htons(ETH_P_IPV6))
8888
goto out;
8989

9090
/* Assignment additions go below here */

packet02-rewriting/xdp_prog_kern.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ int xdp_parser_func(struct xdp_md *ctx)
116116
*/
117117
nh_type = parse_ethhdr(&nh, data_end, &eth);
118118

119-
if (nh_type == ETH_P_IPV6) {
119+
if (nh_type == bpf_htons(ETH_P_IPV6)) {
120120
struct ipv6hdr *ip6h;
121121
struct icmp6hdr *icmp6h;
122122

@@ -131,7 +131,7 @@ int xdp_parser_func(struct xdp_md *ctx)
131131
if (bpf_ntohs(icmp6h->icmp6_sequence) % 2 == 0)
132132
action = XDP_DROP;
133133

134-
} else if (nh_type == ETH_P_IP) {
134+
} else if (nh_type == bpf_htons(ETH_P_IP)) {
135135
struct iphdr *iph;
136136
struct icmphdr *icmph;
137137

packet03-redirecting/xdp_prog_kern.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ int xdp_icmp_echo_func(struct xdp_md *ctx)
6666

6767
/* Parse Ethernet and IP/IPv6 headers */
6868
eth_type = parse_ethhdr(&nh, data_end, &eth);
69-
if (eth_type == ETH_P_IP) {
69+
if (eth_type == bpf_htons(ETH_P_IP)) {
7070
ip_type = parse_iphdr(&nh, data_end, &iphdr);
7171
if (ip_type != IPPROTO_ICMP)
7272
goto out;
73-
} else if (eth_type == ETH_P_IPV6) {
73+
} else if (eth_type == bpf_htons(ETH_P_IPV6)) {
7474
ip_type = parse_ip6hdr(&nh, data_end, &ipv6hdr);
7575
if (ip_type != IPPROTO_ICMPV6)
7676
goto out;
@@ -85,11 +85,12 @@ int xdp_icmp_echo_func(struct xdp_md *ctx)
8585
* the rest of the structure.
8686
*/
8787
icmp_type = parse_icmphdr_common(&nh, data_end, &icmphdr);
88-
if (eth_type == ETH_P_IP && icmp_type == ICMP_ECHO) {
88+
if (eth_type == bpf_htons(ETH_P_IP) && icmp_type == ICMP_ECHO) {
8989
/* Swap IP source and destination */
9090
swap_src_dst_ipv4(iphdr);
9191
echo_reply = ICMP_ECHOREPLY;
92-
} else if (eth_type == ETH_P_IPV6 && icmp_type == ICMPV6_ECHO_REQUEST) {
92+
} else if (eth_type == bpf_htons(ETH_P_IPV6)
93+
&& icmp_type == ICMPV6_ECHO_REQUEST) {
9394
/* Swap IPv6 source and destination */
9495
swap_src_dst_ipv6(ipv6hdr);
9596
echo_reply = ICMPV6_ECHO_REPLY;

0 commit comments

Comments
 (0)