Merge branch 'bpf-misc'
authorDavid S. Miller <davem@davemloft.net>
Fri, 18 Mar 2016 23:38:53 +0000 (19:38 -0400)
committerDavid S. Miller <davem@davemloft.net>
Fri, 18 Mar 2016 23:38:53 +0000 (19:38 -0400)
Daniel Borkmann says:

====================
Minor BPF follow-ups

Some minor last follow-ups I still had in my queue. The first one adds
readability support for __sk_buff's tc_classid member, the remaining
two are some minor cleanups. For details please see individual patches.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/dst.h
include/net/ip_tunnels.h
net/core/filter.c
net/ipv4/ip_tunnel_core.c
net/openvswitch/flow.h

index c7329dcd90cc0637e16fe65eb78246a5d8d21521..5c98443c1c9ef7eb035616d5815c347be211567b 100644 (file)
@@ -398,6 +398,18 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev,
        __skb_tunnel_rx(skb, dev, net);
 }
 
+static inline u32 dst_tclassid(const struct sk_buff *skb)
+{
+#ifdef CONFIG_IP_ROUTE_CLASSID
+       const struct dst_entry *dst;
+
+       dst = skb_dst(skb);
+       if (dst)
+               return dst->tclassid;
+#endif
+       return 0;
+}
+
 int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb);
 static inline int dst_discard(struct sk_buff *skb)
 {
index 5dc2e454f866989cd6c2eae974453ed3b3a8cd0b..c35dda9ec991163f78736ebcd4e61d07683a7e4c 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/socket.h>
 #include <linux/types.h>
 #include <linux/u64_stats_sync.h>
+#include <linux/bitops.h>
+
 #include <net/dsfield.h>
 #include <net/gro_cells.h>
 #include <net/inet_ecn.h>
@@ -57,6 +59,11 @@ struct ip_tunnel_key {
 #define IP_TUNNEL_INFO_TX      0x01    /* represents tx tunnel parameters */
 #define IP_TUNNEL_INFO_IPV6    0x02    /* key contains IPv6 addresses */
 
+/* Maximum tunnel options length. */
+#define IP_TUNNEL_OPTS_MAX                                     \
+       GENMASK((FIELD_SIZEOF(struct ip_tunnel_info,            \
+                             options_len) * BITS_PER_BYTE) - 1, 0)
+
 struct ip_tunnel_info {
        struct ip_tunnel_key    key;
 #ifdef CONFIG_DST_CACHE
index 6fc3893a6170517d3e41f3b4243bf76af5f55bcf..b7177d01ecb097ce69cede880e929a664f42774c 100644 (file)
@@ -1682,14 +1682,7 @@ static const struct bpf_func_proto bpf_get_cgroup_classid_proto = {
 
 static u64 bpf_get_route_realm(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
 {
-#ifdef CONFIG_IP_ROUTE_CLASSID
-       const struct dst_entry *dst;
-
-       dst = skb_dst((struct sk_buff *) (unsigned long) r1);
-       if (dst)
-               return dst->tclassid;
-#endif
-       return 0;
+       return dst_tclassid((struct sk_buff *) (unsigned long) r1);
 }
 
 static 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 = {
        .arg4_type      = ARG_ANYTHING,
 };
 
-#define BPF_TUNLEN_MAX 255
-
 static u64 bpf_skb_set_tunnel_opt(u64 r1, u64 r2, u64 size, u64 r4, u64 r5)
 {
        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)
 
        if (unlikely(info != &md->u.tun_info || (size & (sizeof(u32) - 1))))
                return -EINVAL;
-       if (unlikely(size > BPF_TUNLEN_MAX))
+       if (unlikely(size > IP_TUNNEL_OPTS_MAX))
                return -ENOMEM;
 
        ip_tunnel_info_opts_set(info, from, size);
@@ -1943,13 +1934,10 @@ static const struct bpf_func_proto *
 bpf_get_skb_set_tunnel_proto(enum bpf_func_id which)
 {
        if (!md_dst) {
-               BUILD_BUG_ON(FIELD_SIZEOF(struct ip_tunnel_info,
-                                         options_len) != 1);
-
                /* Race is not possible, since it's called from verifier
                 * that is holding verifier mutex.
                 */
-               md_dst = metadata_dst_alloc_percpu(BPF_TUNLEN_MAX,
+               md_dst = metadata_dst_alloc_percpu(IP_TUNNEL_OPTS_MAX,
                                                   GFP_KERNEL);
                if (!md_dst)
                        return NULL;
@@ -2069,16 +2057,14 @@ static bool sk_filter_is_valid_access(int off, int size,
 static bool tc_cls_act_is_valid_access(int off, int size,
                                       enum bpf_access_type type)
 {
-       if (off == offsetof(struct __sk_buff, tc_classid))
-               return type == BPF_WRITE ? true : false;
-
        if (type == BPF_WRITE) {
                switch (off) {
                case offsetof(struct __sk_buff, mark):
                case offsetof(struct __sk_buff, tc_index):
                case offsetof(struct __sk_buff, priority):
                case offsetof(struct __sk_buff, cb[0]) ...
-                       offsetof(struct __sk_buff, cb[4]):
+                    offsetof(struct __sk_buff, cb[4]):
+               case offsetof(struct __sk_buff, tc_classid):
                        break;
                default:
                        return false;
@@ -2195,8 +2181,10 @@ static u32 bpf_net_convert_ctx_access(enum bpf_access_type type, int dst_reg,
                ctx_off -= offsetof(struct __sk_buff, tc_classid);
                ctx_off += offsetof(struct sk_buff, cb);
                ctx_off += offsetof(struct qdisc_skb_cb, tc_classid);
-               WARN_ON(type != BPF_WRITE);
-               *insn++ = BPF_STX_MEM(BPF_H, dst_reg, src_reg, ctx_off);
+               if (type == BPF_WRITE)
+                       *insn++ = BPF_STX_MEM(BPF_H, dst_reg, src_reg, ctx_off);
+               else
+                       *insn++ = BPF_LDX_MEM(BPF_H, dst_reg, src_reg, ctx_off);
                break;
 
        case offsetof(struct __sk_buff, tc_index):
index eaca2449a09acae2374e4cb4a629702f95c5b510..d27276f6f8ddcd4d359b26b17b869a8ccd2cb929 100644 (file)
@@ -398,6 +398,12 @@ static const struct lwtunnel_encap_ops ip6_tun_lwt_ops = {
 
 void __init ip_tunnel_core_init(void)
 {
+       /* If you land here, make sure whether increasing ip_tunnel_info's
+        * options_len is a reasonable choice with its usage in front ends
+        * (f.e., it's part of flow keys, etc).
+        */
+       BUILD_BUG_ON(IP_TUNNEL_OPTS_MAX != 255);
+
        lwtunnel_encap_add_ops(&ip_tun_lwt_ops, LWTUNNEL_ENCAP_IP);
        lwtunnel_encap_add_ops(&ip6_tun_lwt_ops, LWTUNNEL_ENCAP_IP6);
 }
index 1d055c559eafb118043ed21c66916d7313c41d8d..03378e75a67c0807b5a362a5ca95cf13cfee3917 100644 (file)
@@ -55,7 +55,7 @@ struct ovs_tunnel_info {
        FIELD_SIZEOF(struct sw_flow_key, recirc_id))
 
 struct sw_flow_key {
-       u8 tun_opts[255];
+       u8 tun_opts[IP_TUNNEL_OPTS_MAX];
        u8 tun_opts_len;
        struct ip_tunnel_key tun_key;   /* Encapsulating tunnel key. */
        struct {