Skip to content

Commit d471043

Browse files
avasylevfacebook-github-bot
authored andcommitted
Move process_l3_headers to pckt_parsing.h
Summary: Make it re-usable, copy pasted function as-is. Reviewed By: frankfeir Differential Revision: D70989396 fbshipit-source-id: 78040e26430dd3345efa48cf10cc7b60fa1a26bb
1 parent 020aa12 commit d471043

File tree

2 files changed

+70
-70
lines changed

2 files changed

+70
-70
lines changed

katran/lib/bpf/balancer.bpf.c

+2-70
Original file line numberDiff line numberDiff line change
@@ -198,74 +198,6 @@ __attribute__((__always_inline__)) static inline void connection_table_lookup(
198198
return;
199199
}
200200

201-
__attribute__((__always_inline__)) static inline int process_l3_headers(
202-
struct packet_description* pckt,
203-
__u8* protocol,
204-
__u64 nh_off, // network header offset (IPv4/IPv6)
205-
__u64* th_off, // transport header offset (TCP/UDP/...)
206-
__u16* pkt_bytes,
207-
void* data,
208-
void* data_end,
209-
bool is_ipv6) {
210-
__u64 iph_len;
211-
struct iphdr* iph;
212-
struct ipv6hdr* ip6h;
213-
if (is_ipv6) {
214-
ip6h = data + nh_off;
215-
if (ip6h + 1 > data_end) {
216-
return XDP_DROP;
217-
}
218-
219-
iph_len = sizeof(struct ipv6hdr);
220-
*protocol = ip6h->nexthdr;
221-
pckt->flow.proto = *protocol;
222-
223-
// copy tos from the packet
224-
pckt->tos = (ip6h->priority << 4) & 0xF0;
225-
pckt->tos = pckt->tos | ((ip6h->flow_lbl[0] >> 4) & 0x0F);
226-
227-
*pkt_bytes = bpf_ntohs(ip6h->payload_len);
228-
*th_off += nh_off + iph_len;
229-
if (*protocol == IPPROTO_FRAGMENT) {
230-
// we drop fragmented packets
231-
return XDP_DROP;
232-
} else if (*protocol == IPPROTO_ICMPV6) {
233-
return FURTHER_PROCESSING;
234-
} else {
235-
memcpy(pckt->flow.srcv6, ip6h->saddr.s6_addr32, 16);
236-
memcpy(pckt->flow.dstv6, ip6h->daddr.s6_addr32, 16);
237-
}
238-
} else {
239-
iph = data + nh_off;
240-
if (iph + 1 > data_end) {
241-
return XDP_DROP;
242-
}
243-
// ihl contains len of ipv4 header in 32bit words
244-
if (iph->ihl != 5) {
245-
// if len of ipv4 hdr is not equal to 20bytes that means that header
246-
// contains ip options, and we dont support em
247-
return XDP_DROP;
248-
}
249-
pckt->tos = iph->tos;
250-
*protocol = iph->protocol;
251-
pckt->flow.proto = *protocol;
252-
*pkt_bytes = bpf_ntohs(iph->tot_len);
253-
*th_off += nh_off + IPV4_HDR_LEN_NO_OPT;
254-
255-
if (iph->frag_off & PCKT_FRAGMENTED) {
256-
// we drop fragmented packets.
257-
return XDP_DROP;
258-
}
259-
if (*protocol == IPPROTO_ICMP) {
260-
return FURTHER_PROCESSING;
261-
} else {
262-
pckt->flow.src = iph->saddr;
263-
pckt->flow.dst = iph->daddr;
264-
}
265-
}
266-
return FURTHER_PROCESSING;
267-
}
268-
269201
#ifdef INLINE_DECAP_GENERIC
270202
__attribute__((__always_inline__)) static inline int
271203
check_decap_dst(struct packet_description* pckt, bool is_ipv6, bool* pass) {
@@ -437,7 +369,7 @@ incr_decap_vip_stats(void* data, __u64 nh_off, void* data_end, bool is_ipv6) {
437369
__u8 inner_protocol;
438370
__u16 inner_pkt_bytes;
439371
__u64 th_off = 0;
440-
if (process_l3_headers(
372+
if (parse_l3_headers(
441373
&inner_pckt,
442374
&inner_protocol,
443375
nh_off,
@@ -711,7 +643,7 @@ process_packet(struct xdp_md* xdp, __u64 nh_off, bool is_ipv6) {
711643
__u32 mac_addr_pos = 0;
712644
__u16 pkt_bytes;
713645
__u64 th_off = 0;
714-
action = process_l3_headers(
646+
action = parse_l3_headers(
715647
&pckt, &protocol, nh_off, &th_off, &pkt_bytes, data, data_end, is_ipv6);
716648
if (action >= 0) {
717649
return action;

katran/lib/bpf/pckt_parsing.h

+68
Original file line numberDiff line numberDiff line change
@@ -464,4 +464,72 @@ parse_udp_stable_rt_hdr(
464464
return result;
465465
}
466466

467+
__attribute__((__always_inline__)) static inline int parse_l3_headers(
468+
struct packet_description* pckt,
469+
__u8* protocol,
470+
__u64 nh_off, // network header offset (IPv4/IPv6)
471+
__u64* th_off, // transport header offset (TCP/UDP/...)
472+
__u16* pkt_bytes,
473+
void* data,
474+
void* data_end,
475+
bool is_ipv6) {
476+
__u64 iph_len;
477+
struct iphdr* iph;
478+
struct ipv6hdr* ip6h;
479+
if (is_ipv6) {
480+
ip6h = data + nh_off;
481+
if (ip6h + 1 > data_end) {
482+
return XDP_DROP;
483+
}
484+
485+
iph_len = sizeof(struct ipv6hdr);
486+
*protocol = ip6h->nexthdr;
487+
pckt->flow.proto = *protocol;
488+
489+
// copy tos from the packet
490+
pckt->tos = (ip6h->priority << 4) & 0xF0;
491+
pckt->tos = pckt->tos | ((ip6h->flow_lbl[0] >> 4) & 0x0F);
492+
493+
*pkt_bytes = bpf_ntohs(ip6h->payload_len);
494+
*th_off += nh_off + iph_len;
495+
if (*protocol == IPPROTO_FRAGMENT) {
496+
// we drop fragmented packets
497+
return XDP_DROP;
498+
} else if (*protocol == IPPROTO_ICMPV6) {
499+
return FURTHER_PROCESSING;
500+
} else {
501+
memcpy(pckt->flow.srcv6, ip6h->saddr.s6_addr32, 16);
502+
memcpy(pckt->flow.dstv6, ip6h->daddr.s6_addr32, 16);
503+
}
504+
} else {
505+
iph = data + nh_off;
506+
if (iph + 1 > data_end) {
507+
return XDP_DROP;
508+
}
509+
// ihl contains len of ipv4 header in 32bit words
510+
if (iph->ihl != 5) {
511+
// if len of ipv4 hdr is not equal to 20bytes that means that header
512+
// contains ip options, and we dont support em
513+
return XDP_DROP;
514+
}
515+
pckt->tos = iph->tos;
516+
*protocol = iph->protocol;
517+
pckt->flow.proto = *protocol;
518+
*pkt_bytes = bpf_ntohs(iph->tot_len);
519+
*th_off += nh_off + IPV4_HDR_LEN_NO_OPT;
520+
521+
if (iph->frag_off & PCKT_FRAGMENTED) {
522+
// we drop fragmented packets.
523+
return XDP_DROP;
524+
}
525+
if (*protocol == IPPROTO_ICMP) {
526+
return FURTHER_PROCESSING;
527+
} else {
528+
pckt->flow.src = iph->saddr;
529+
pckt->flow.dst = iph->daddr;
530+
}
531+
}
532+
return FURTHER_PROCESSING;
533+
}
534+
467535
#endif // of __PCKT_PARSING_H

0 commit comments

Comments
 (0)