diff options
| author | Daniel Borkmann <daniel@iogearbox.net> | 2016-03-15 20:42:51 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-03-18 19:38:46 -0400 |
| commit | fca5fdf67de9e092fda23c9eb059ba968e7b5267 (patch) | |
| tree | 06aa42e0d7679a15e223a05acd202d2897252bb1 | |
| parent | 808c1b697c3c4dd2a7132882424c390b0d0acfb9 (diff) | |
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>
| -rw-r--r-- | include/net/ip_tunnels.h | 7 | ||||
| -rw-r--r-- | net/core/filter.c | 9 | ||||
| -rw-r--r-- | net/ipv4/ip_tunnel_core.c | 6 | ||||
| -rw-r--r-- | net/openvswitch/flow.h | 2 |
4 files changed, 16 insertions, 8 deletions
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 5dc2e454f866..c35dda9ec991 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <linux/socket.h> | 7 | #include <linux/socket.h> |
| 8 | #include <linux/types.h> | 8 | #include <linux/types.h> |
| 9 | #include <linux/u64_stats_sync.h> | 9 | #include <linux/u64_stats_sync.h> |
| 10 | #include <linux/bitops.h> | ||
| 11 | |||
| 10 | #include <net/dsfield.h> | 12 | #include <net/dsfield.h> |
| 11 | #include <net/gro_cells.h> | 13 | #include <net/gro_cells.h> |
| 12 | #include <net/inet_ecn.h> | 14 | #include <net/inet_ecn.h> |
| @@ -57,6 +59,11 @@ struct ip_tunnel_key { | |||
| 57 | #define IP_TUNNEL_INFO_TX 0x01 /* represents tx tunnel parameters */ | 59 | #define IP_TUNNEL_INFO_TX 0x01 /* represents tx tunnel parameters */ |
| 58 | #define IP_TUNNEL_INFO_IPV6 0x02 /* key contains IPv6 addresses */ | 60 | #define IP_TUNNEL_INFO_IPV6 0x02 /* key contains IPv6 addresses */ |
| 59 | 61 | ||
| 62 | /* Maximum tunnel options length. */ | ||
| 63 | #define IP_TUNNEL_OPTS_MAX \ | ||
| 64 | GENMASK((FIELD_SIZEOF(struct ip_tunnel_info, \ | ||
| 65 | options_len) * BITS_PER_BYTE) - 1, 0) | ||
| 66 | |||
| 60 | struct ip_tunnel_info { | 67 | struct ip_tunnel_info { |
| 61 | struct ip_tunnel_key key; | 68 | struct ip_tunnel_key key; |
| 62 | #ifdef CONFIG_DST_CACHE | 69 | #ifdef CONFIG_DST_CACHE |
diff --git a/net/core/filter.c b/net/core/filter.c index 4c35d8325c34..b7177d01ecb0 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -1904,8 +1904,6 @@ static const struct bpf_func_proto bpf_skb_set_tunnel_key_proto = { | |||
| 1904 | .arg4_type = ARG_ANYTHING, | 1904 | .arg4_type = ARG_ANYTHING, |
| 1905 | }; | 1905 | }; |
| 1906 | 1906 | ||
| 1907 | #define BPF_TUNLEN_MAX 255 | ||
| 1908 | |||
| 1909 | static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5) | 1907 | static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5) |
| 1910 | { | 1908 | { |
| 1911 | struct sk_buff *skb = (struct sk_buff *) (long) r1; | 1909 | struct sk_buff *skb = (struct sk_buff *) (long) r1; |
| @@ -1915,7 +1913,7 @@ static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5) | |||
| 1915 | 1913 | ||
| 1916 | if (unlikely(info != &md->u.tun_info || (size & (sizeof(u32) - 1)))) | 1914 | if (unlikely(info != &md->u.tun_info || (size & (sizeof(u32) - 1)))) |
| 1917 | return -EINVAL; | 1915 | return -EINVAL; |
| 1918 | if (unlikely(size > BPF_TUNLEN_MAX)) | 1916 | if (unlikely(size > IP_TUNNEL_OPTS_MAX)) |
| 1919 | return -ENOMEM; | 1917 | return -ENOMEM; |
| 1920 | 1918 | ||
| 1921 | ip_tunnel_info_opts_set(info, from, size); | 1919 | ip_tunnel_info_opts_set(info, from, size); |
| @@ -1936,13 +1934,10 @@ static const struct bpf_func_proto * | |||
| 1936 | bpf_get_skb_set_tunnel_proto(enum bpf_func_id which) | 1934 | bpf_get_skb_set_tunnel_proto(enum bpf_func_id which) |
| 1937 | { | 1935 | { |
| 1938 | if (!md_dst) { | 1936 | if (!md_dst) { |
| 1939 | BUILD_BUG_ON(FIELD_SIZEOF(struct ip_tunnel_info, | ||
| 1940 | options_len) != 1); | ||
| 1941 | |||
| 1942 | /* Race is not possible, since it's called from verifier | 1937 | /* Race is not possible, since it's called from verifier |
| 1943 | * that is holding verifier mutex. | 1938 | * that is holding verifier mutex. |
| 1944 | */ | 1939 | */ |
| 1945 | md_dst = metadata_dst_alloc_percpu(BPF_TUNLEN_MAX, | 1940 | md_dst = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX, |
| 1946 | GFP_KERNEL); | 1941 | GFP_KERNEL); |
| 1947 | if (!md_dst) | 1942 | if (!md_dst) |
| 1948 | return NULL; | 1943 | return NULL; |
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index eaca2449a09a..d27276f6f8dd 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
| @@ -398,6 +398,12 @@ static const struct lwtunnel_encap_ops ip6_tun_lwt_ops = { | |||
| 398 | 398 | ||
| 399 | void __init ip_tunnel_core_init(void) | 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 | lwtunnel_encap_add_ops(&ip_tun_lwt_ops, LWTUNNEL_ENCAP_IP); | 407 | lwtunnel_encap_add_ops(&ip_tun_lwt_ops, LWTUNNEL_ENCAP_IP); |
| 402 | lwtunnel_encap_add_ops(&ip6_tun_lwt_ops, LWTUNNEL_ENCAP_IP6); | 408 | lwtunnel_encap_add_ops(&ip6_tun_lwt_ops, LWTUNNEL_ENCAP_IP6); |
| 403 | } | 409 | } |
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 1d055c559eaf..03378e75a67c 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
| @@ -55,7 +55,7 @@ struct ovs_tunnel_info { | |||
| 55 | FIELD_SIZEOF(struct sw_flow_key, recirc_id)) | 55 | FIELD_SIZEOF(struct sw_flow_key, recirc_id)) |
| 56 | 56 | ||
| 57 | struct sw_flow_key { | 57 | struct sw_flow_key { |
| 58 | u8 tun_opts[255]; | 58 | u8 tun_opts[IP_TUNNEL_OPTS_MAX]; |
| 59 | u8 tun_opts_len; | 59 | u8 tun_opts_len; |
| 60 | struct ip_tunnel_key tun_key; /* Encapsulating tunnel key. */ | 60 | struct ip_tunnel_key tun_key; /* Encapsulating tunnel key. */ |
| 61 | struct { | 61 | struct { |
