Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:Update
libteam
0001-teamd-do-correct-l3-l4-tx-hashing-with-vla...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-teamd-do-correct-l3-l4-tx-hashing-with-vlans.patch of Package libteam
From 6d54ab1b218a1253a3fb760766d43fc20ae35cbe Mon Sep 17 00:00:00 2001 From: Antti Tiainen <atiainen@forcepoint.com> Date: Fri, 26 Feb 2016 14:52:38 +0200 Subject: [PATCH] teamd: do correct l3/l4 tx hashing with vlans bpf_create_code() is not creating correct hashing code with vlan tagged packets. L3/l4 headers are not included to hash even when configured. There were three problems: - VLAN_HEADER_SIZE is wrong. But this doesn't really matter because... - if vlan tagging is offloaded, generated code will find skb->vlan_tci and incorrectly skip non-existent vlan header, failing to find l3 protocol - if vlan tagging is not offloaded, skb->vlan_tci is zeroed in kernel after call to __vlan_put_tag(). Hashing code will not skip VLAN header, failing again to find l3 protocol bpf code must look first for VLAN proto (0x8100) and read the vlan tag from header instead of skb->vlan_tci, and in this case use the correct offset (4) for vlan shift. If VLAN header is not present in packet, skb->vlan_tci must still be checked in case of offloaded vlan header. Signed-off-by: Antti Tiainen <atiainen@forcepoint.com> Acked-by: Flavio Leitner <fbl@sysclose.org> Signed-off-by: Jiri Pirko <jiri@mellanox.com> --- teamd/teamd_bpf_chef.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/teamd/teamd_bpf_chef.c b/teamd/teamd_bpf_chef.c index 15622e8..2482c10 100644 --- a/teamd/teamd_bpf_chef.c +++ b/teamd/teamd_bpf_chef.c @@ -26,6 +26,7 @@ /* protocol offsets */ #define ETH_TYPE_OFFSET 12 +#define VLAN_TAG_OFFSET 14 #define IPV4_FLAGS_OFFSET 20 #define IPV4_PROTO_OFFSET 23 #define IPV4_FRAG_BITS 0x1fff @@ -35,6 +36,7 @@ /* protocol codes */ #define PROTOID_IPV4 0x800 #define PROTOID_IPV6 0x86dd +#define PROTOID_VLAN 0x8100 #define PROTOID_TCP 0x6 #define PROTOID_UDP 0x11 #define PROTOID_SCTP 0x84 @@ -45,7 +47,7 @@ #define FIX_K 0x4 -#define VLAN_HEADER_SIZE 2 +#define VLAN_HEADER_SIZE 4 static int vlan_hdr_shift(unsigned int offset) { return offset + VLAN_HEADER_SIZE; @@ -83,6 +85,9 @@ static int __add_inst(struct sock_fprog *fprog, struct sock_filter *inst) #define bpf_load_word(pos) \ add_inst(fprog, BPF_STMT(BPF_LD + BPF_W + BPF_ABS, pos)) +#define bpf_and_word(w) \ + add_inst(fprog, BPF_STMT(BPF_AND + BPF_ALU, w)) + #define bpf_push_a() \ add_inst(fprog, BPF_STMT(BPF_ST, 0)) @@ -150,6 +155,7 @@ static int __add_inst(struct sock_fprog *fprog, struct sock_filter *inst) enum bpf_labels { LABEL_VLAN_BRANCH, + LABEL_VLAN_TAG_SKIP, LABEL_NOVLAN_IPV6, LABEL_NOVLAN_L4v4_OUT, LABEL_NOVLAN_TRY_UDP4, @@ -472,6 +478,19 @@ err_add_inst: return err; } +static int bpf_vlan_hash_header(struct sock_fprog *fprog) +{ + int err; + + bpf_load_half(VLAN_TAG_OFFSET); + bpf_and_word(0x0fff); + bpf_calc_hash(); + bpf_move_to_x(); + +err_add_inst: + return err; +} + static int __bpf_ipv4_hash(struct sock_fprog *fprog, bool vlan) { int vlan_shift = vlan ? vlan_hdr_shift(0) : 0; @@ -647,13 +666,25 @@ static int bpf_create_code(struct sock_fprog *fprog, struct hash_flags *flags) return 0; } - bpf_vlan_tag_present(); - bpf_cmp(0, LABEL_VLAN_BRANCH, 0, FIX_JF); + bpf_load_half(ETH_TYPE_OFFSET); + bpf_cmp(LABEL_VLAN_BRANCH, 0, PROTOID_VLAN, FIX_JT); + + /* no vlan branch, but might be offloaded */ + if (hash_test_and_set_flag(flags, HASH_VLAN)) { + bpf_vlan_tag_present(); + bpf_cmp(LABEL_VLAN_TAG_SKIP, 0, 0, FIX_JT); + bpf_vlan_hash(fprog); + push_label(fprog, LABEL_VLAN_TAG_SKIP); + } + if (!hash_is_novlan_l3l4_enabled(flags)) bpf_hash_return(); + /* vlan hashing overwrote this */ + if (hash_is_enabled(flags, HASH_VLAN)) + bpf_load_half(ETH_TYPE_OFFSET); + /* no vlan branch */ - bpf_load_half(ETH_TYPE_OFFSET); bpf_cmp(0, LABEL_NOVLAN_IPV6, PROTOID_IPV4, FIX_JF); /* no vlan ipv4 branch */ @@ -747,7 +778,7 @@ static int bpf_create_code(struct sock_fprog *fprog, struct hash_flags *flags) /* vlan branch */ push_label(fprog, LABEL_VLAN_BRANCH); if (hash_test_and_set_flag(flags, HASH_VLAN)) - bpf_vlan_hash(fprog); + bpf_vlan_hash_header(fprog); if (hash_is_complete(flags)) { bpf_hash_return(); -- 2.21.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor