Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ip_tunnels, bpf: define IP_TUNNEL_OPTS_MAX and use it

eBPF defines this as BPF_TUNLEN_MAX and OVS just uses the hard-coded
value inside struct sw_flow_key. Thus, add and use IP_TUNNEL_OPTS_MAX
for this, which makes the code a bit more generic and allows to remove
BPF_TUNLEN_MAX from eBPF code.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Daniel Borkmann and committed by
David S. Miller
fca5fdf6 808c1b69

+16 -8
+7
include/net/ip_tunnels.h
··· 7 7 #include <linux/socket.h> 8 8 #include <linux/types.h> 9 9 #include <linux/u64_stats_sync.h> 10 + #include <linux/bitops.h> 11 + 10 12 #include <net/dsfield.h> 11 13 #include <net/gro_cells.h> 12 14 #include <net/inet_ecn.h> ··· 58 56 /* Flags for ip_tunnel_info mode. */ 59 57 #define IP_TUNNEL_INFO_TX 0x01 /* represents tx tunnel parameters */ 60 58 #define IP_TUNNEL_INFO_IPV6 0x02 /* key contains IPv6 addresses */ 59 + 60 + /* Maximum tunnel options length. */ 61 + #define IP_TUNNEL_OPTS_MAX \ 62 + GENMASK((FIELD_SIZEOF(struct ip_tunnel_info, \ 63 + options_len) * BITS_PER_BYTE) - 1, 0) 61 64 62 65 struct ip_tunnel_info { 63 66 struct ip_tunnel_key key;
+2 -7
net/core/filter.c
··· 1904 1904 .arg4_type = ARG_ANYTHING, 1905 1905 }; 1906 1906 1907 - #define BPF_TUNLEN_MAX 255 1908 - 1909 1907 static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5) 1910 1908 { 1911 1909 struct sk_buff *skb = (struct sk_buff *) (long) r1; ··· 1913 1915 1914 1916 if (unlikely(info != &md->u.tun_info || (size & (sizeof(u32) - 1)))) 1915 1917 return -EINVAL; 1916 - if (unlikely(size > BPF_TUNLEN_MAX)) 1918 + if (unlikely(size > IP_TUNNEL_OPTS_MAX)) 1917 1919 return -ENOMEM; 1918 1920 1919 1921 ip_tunnel_info_opts_set(info, from, size); ··· 1934 1936 bpf_get_skb_set_tunnel_proto(enum bpf_func_id which) 1935 1937 { 1936 1938 if (!md_dst) { 1937 - BUILD_BUG_ON(FIELD_SIZEOF(struct ip_tunnel_info, 1938 - options_len) != 1); 1939 - 1940 1939 /* Race is not possible, since it's called from verifier 1941 1940 * that is holding verifier mutex. 1942 1941 */ 1943 - md_dst = metadata_dst_alloc_percpu(BPF_TUNLEN_MAX, 1942 + md_dst = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX, 1944 1943 GFP_KERNEL); 1945 1944 if (!md_dst) 1946 1945 return NULL;
+6
net/ipv4/ip_tunnel_core.c
··· 398 398 399 399 void __init ip_tunnel_core_init(void) 400 400 { 401 + /* If you land here, make sure whether increasing ip_tunnel_info's 402 + * options_len is a reasonable choice with its usage in front ends 403 + * (f.e., it's part of flow keys, etc). 404 + */ 405 + BUILD_BUG_ON(IP_TUNNEL_OPTS_MAX != 255); 406 + 401 407 lwtunnel_encap_add_ops(&ip_tun_lwt_ops, LWTUNNEL_ENCAP_IP); 402 408 lwtunnel_encap_add_ops(&ip6_tun_lwt_ops, LWTUNNEL_ENCAP_IP6); 403 409 }
+1 -1
net/openvswitch/flow.h
··· 55 55 FIELD_SIZEOF(struct sw_flow_key, recirc_id)) 56 56 57 57 struct sw_flow_key { 58 - u8 tun_opts[255]; 58 + u8 tun_opts[IP_TUNNEL_OPTS_MAX]; 59 59 u8 tun_opts_len; 60 60 struct ip_tunnel_key tun_key; /* Encapsulating tunnel key. */ 61 61 struct {