提交 4018ab18 编写于 作者: D Daniel Borkmann 提交者: David S. Miller

bpf: support flow label for bpf_skb_{set, get}_tunnel_key

This patch extends bpf_tunnel_key with a tunnel_label member, that maps
to ip_tunnel_key's label so underlying backends like vxlan and geneve
can propagate the label to udp_tunnel6_xmit_skb(), where it's being set
in the IPv6 header. It allows for having 20 more bits to encode/decode
flow related meta information programmatically. Tested with vxlan and
geneve.
Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
Acked-by: NAlexei Starovoitov <ast@kernel.org>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 8eb3b995
...@@ -375,6 +375,7 @@ struct bpf_tunnel_key { ...@@ -375,6 +375,7 @@ struct bpf_tunnel_key {
}; };
__u8 tunnel_tos; __u8 tunnel_tos;
__u8 tunnel_ttl; __u8 tunnel_ttl;
__u32 tunnel_label;
}; };
#endif /* _UAPI__LINUX_BPF_H__ */ #endif /* _UAPI__LINUX_BPF_H__ */
...@@ -1770,12 +1770,15 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) ...@@ -1770,12 +1770,15 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
return -EPROTO; return -EPROTO;
if (unlikely(size != sizeof(struct bpf_tunnel_key))) { if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
switch (size) { switch (size) {
case offsetof(struct bpf_tunnel_key, tunnel_label):
goto set_compat;
case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): case offsetof(struct bpf_tunnel_key, remote_ipv6[1]):
/* Fixup deprecated structure layouts here, so we have /* Fixup deprecated structure layouts here, so we have
* a common path later on. * a common path later on.
*/ */
if (ip_tunnel_info_af(info) != AF_INET) if (ip_tunnel_info_af(info) != AF_INET)
return -EINVAL; return -EINVAL;
set_compat:
to = (struct bpf_tunnel_key *)compat; to = (struct bpf_tunnel_key *)compat;
break; break;
default: default:
...@@ -1787,11 +1790,13 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) ...@@ -1787,11 +1790,13 @@ static u64 bpf_skb_get_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
to->tunnel_tos = info->key.tos; to->tunnel_tos = info->key.tos;
to->tunnel_ttl = info->key.ttl; to->tunnel_ttl = info->key.ttl;
if (flags & BPF_F_TUNINFO_IPV6) if (flags & BPF_F_TUNINFO_IPV6) {
memcpy(to->remote_ipv6, &info->key.u.ipv6.src, memcpy(to->remote_ipv6, &info->key.u.ipv6.src,
sizeof(to->remote_ipv6)); sizeof(to->remote_ipv6));
else to->tunnel_label = be32_to_cpu(info->key.label);
} else {
to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src); to->remote_ipv4 = be32_to_cpu(info->key.u.ipv4.src);
}
if (unlikely(size != sizeof(struct bpf_tunnel_key))) if (unlikely(size != sizeof(struct bpf_tunnel_key)))
memcpy((void *)(long) r2, to, size); memcpy((void *)(long) r2, to, size);
...@@ -1850,6 +1855,7 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) ...@@ -1850,6 +1855,7 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
return -EINVAL; return -EINVAL;
if (unlikely(size != sizeof(struct bpf_tunnel_key))) { if (unlikely(size != sizeof(struct bpf_tunnel_key))) {
switch (size) { switch (size) {
case offsetof(struct bpf_tunnel_key, tunnel_label):
case offsetof(struct bpf_tunnel_key, remote_ipv6[1]): case offsetof(struct bpf_tunnel_key, remote_ipv6[1]):
/* Fixup deprecated structure layouts here, so we have /* Fixup deprecated structure layouts here, so we have
* a common path later on. * a common path later on.
...@@ -1862,6 +1868,8 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) ...@@ -1862,6 +1868,8 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
return -EINVAL; return -EINVAL;
} }
} }
if (unlikely(!(flags & BPF_F_TUNINFO_IPV6) && from->tunnel_label))
return -EINVAL;
skb_dst_drop(skb); skb_dst_drop(skb);
dst_hold((struct dst_entry *) md); dst_hold((struct dst_entry *) md);
...@@ -1882,6 +1890,8 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5) ...@@ -1882,6 +1890,8 @@ static u64 bpf_skb_set_tunnel_key(u64 r1, u64 r2, u64 size, u64 flags, u64 r5)
info->mode |= IP_TUNNEL_INFO_IPV6; info->mode |= IP_TUNNEL_INFO_IPV6;
memcpy(&info->key.u.ipv6.dst, from->remote_ipv6, memcpy(&info->key.u.ipv6.dst, from->remote_ipv6,
sizeof(from->remote_ipv6)); sizeof(from->remote_ipv6));
info->key.label = cpu_to_be32(from->tunnel_label) &
IPV6_FLOWLABEL_MASK;
} else { } else {
info->key.u.ipv4.dst = cpu_to_be32(from->remote_ipv4); info->key.u.ipv4.dst = cpu_to_be32(from->remote_ipv4);
if (flags & BPF_F_ZERO_CSUM_TX) if (flags & BPF_F_ZERO_CSUM_TX)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册