aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/dst.h12
-rw-r--r--include/net/ip_tunnels.h7
-rw-r--r--net/core/filter.c30
-rw-r--r--net/ipv4/ip_tunnel_core.c6
-rw-r--r--net/openvswitch/flow.h2
5 files changed, 35 insertions, 22 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index c7329dcd90cc..5c98443c1c9e 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -398,6 +398,18 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
398 __skb_tunnel_rx(skb, dev, net); 398 __skb_tunnel_rx(skb, dev, net);
399} 399}
400 400
401static inline u32 dst_tclassid(const struct sk_buff *skb)
402{
403#ifdef CONFIG_IP_ROUTE_CLASSID
404 const struct dst_entry *dst;
405
406 dst = skb_dst(skb);
407 if (dst)
408 return dst->tclassid;
409#endif
410 return 0;
411}
412
401int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); 413int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
402static inline int dst_discard(struct sk_buff *skb) 414static inline int dst_discard(struct sk_buff *skb)
403{ 415{
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
60struct ip_tunnel_info { 67struct 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 6fc3893a6170..b7177d01ecb0 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1682,14 +1682,7 @@ static const struct bpf_func_proto bpf_get_cgroup_classid_proto = {
1682 1682
1683static u64 bpf_get_route_realm(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) 1683static u64 bpf_get_route_realm(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
1684{ 1684{
1685#ifdef CONFIG_IP_ROUTE_CLASSID 1685 return dst_tclassid((struct sk_buff *) (unsigned long) r1);
1686 const struct dst_entry *dst;
1687
1688 dst = skb_dst((struct sk_buff *) (unsigned long) r1);
1689 if (dst)
1690 return dst->tclassid;
1691#endif
1692 return 0;
1693} 1686}
1694 1687
1695static const struct bpf_func_proto bpf_get_route_realm_proto = { 1688static const struct bpf_func_proto bpf_get_route_realm_proto = {
@@ -1911,8 +1904,6 @@ static const struct bpf_func_proto bpf_skb_set_tunnel_key_proto = {
1911 .arg4_type = ARG_ANYTHING, 1904 .arg4_type = ARG_ANYTHING,
1912}; 1905};
1913 1906
1914#define BPF_TUNLEN_MAX 255
1915
1916static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5) 1907static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5)
1917{ 1908{
1918 struct sk_buff *skb = (struct sk_buff *) (long) r1; 1909 struct sk_buff *skb = (struct sk_buff *) (long) r1;
@@ -1922,7 +1913,7 @@ static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5)
1922 1913
1923 if (unlikely(info != &md->u.tun_info || (size & (sizeof(u32) - 1)))) 1914 if (unlikely(info != &md->u.tun_info || (size & (sizeof(u32) - 1))))
1924 return -EINVAL; 1915 return -EINVAL;
1925 if (unlikely(size > BPF_TUNLEN_MAX)) 1916 if (unlikely(size > IP_TUNNEL_OPTS_MAX))
1926 return -ENOMEM; 1917 return -ENOMEM;
1927 1918
1928 ip_tunnel_info_opts_set(info, from, size); 1919 ip_tunnel_info_opts_set(info, from, size);
@@ -1943,13 +1934,10 @@ static const struct bpf_func_proto *
1943bpf_get_skb_set_tunnel_proto(enum bpf_func_id which) 1934bpf_get_skb_set_tunnel_proto(enum bpf_func_id which)
1944{ 1935{
1945 if (!md_dst) { 1936 if (!md_dst) {
1946 BUILD_BUG_ON(FIELD_SIZEOF(struct ip_tunnel_info,
1947 options_len) != 1);
1948
1949 /* Race is not possible, since it's called from verifier 1937 /* Race is not possible, since it's called from verifier
1950 * that is holding verifier mutex. 1938 * that is holding verifier mutex.
1951 */ 1939 */
1952 md_dst = metadata_dst_alloc_percpu(BPF_TUNLEN_MAX, 1940 md_dst = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX,
1953 GFP_KERNEL); 1941 GFP_KERNEL);
1954 if (!md_dst) 1942 if (!md_dst)
1955 return NULL; 1943 return NULL;
@@ -2069,16 +2057,14 @@ static bool sk_filter_is_valid_access(int off, int size,
2069static bool tc_cls_act_is_valid_access(int off, int size, 2057static bool tc_cls_act_is_valid_access(int off, int size,
2070 enum bpf_access_type type) 2058 enum bpf_access_type type)
2071{ 2059{
2072 if (off == offsetof(struct __sk_buff, tc_classid))
2073 return type == BPF_WRITE ? true : false;
2074
2075 if (type == BPF_WRITE) { 2060 if (type == BPF_WRITE) {
2076 switch (off) { 2061 switch (off) {
2077 case offsetof(struct __sk_buff, mark): 2062 case offsetof(struct __sk_buff, mark):
2078 case offsetof(struct __sk_buff, tc_index): 2063 case offsetof(struct __sk_buff, tc_index):
2079 case offsetof(struct __sk_buff, priority): 2064 case offsetof(struct __sk_buff, priority):
2080 case offsetof(struct __sk_buff, cb[0]) ... 2065 case offsetof(struct __sk_buff, cb[0]) ...
2081 offsetof(struct __sk_buff, cb[4]): 2066 offsetof(struct __sk_buff, cb[4]):
2067 case offsetof(struct __sk_buff, tc_classid):
2082 break; 2068 break;
2083 default: 2069 default:
2084 return false; 2070 return false;
@@ -2195,8 +2181,10 @@ static u32 bpf_net_convert_ctx_access(enum bpf_access_type type, int dst_reg,
2195 ctx_off -= offsetof(struct __sk_buff, tc_classid); 2181 ctx_off -= offsetof(struct __sk_buff, tc_classid);
2196 ctx_off += offsetof(struct sk_buff, cb); 2182 ctx_off += offsetof(struct sk_buff, cb);
2197 ctx_off += offsetof(struct qdisc_skb_cb, tc_classid); 2183 ctx_off += offsetof(struct qdisc_skb_cb, tc_classid);
2198 WARN_ON(type != BPF_WRITE); 2184 if (type == BPF_WRITE)
2199 *insn++ = BPF_STX_MEM(BPF_H, dst_reg, src_reg, ctx_off); 2185 *insn++ = BPF_STX_MEM(BPF_H, dst_reg, src_reg, ctx_off);
2186 else
2187 *insn++ = BPF_LDX_MEM(BPF_H, dst_reg, src_reg, ctx_off);
2200 break; 2188 break;
2201 2189
2202 case offsetof(struct __sk_buff, tc_index): 2190 case offsetof(struct __sk_buff, tc_index):
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
399void __init ip_tunnel_core_init(void) 399void __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
57struct sw_flow_key { 57struct 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 {