drop_monitor: extend by passing cookie from driver
authorJiri Pirko <jiri@mellanox.com>
Tue, 25 Feb 2020 10:45:20 +0000 (11:45 +0100)
committerDavid S. Miller <davem@davemloft.net>
Tue, 25 Feb 2020 19:05:54 +0000 (11:05 -0800)
If driver passed along the cookie, push it through Netlink.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/drop_monitor.h
include/uapi/linux/net_dropmon.h
net/core/drop_monitor.c

index 2ab6684..ddd441a 100644 (file)
@@ -6,17 +6,20 @@
 #include <linux/ktime.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
+#include <net/flow_offload.h>
 
 /**
  * struct net_dm_hw_metadata - Hardware-supplied packet metadata.
  * @trap_group_name: Hardware trap group name.
  * @trap_name: Hardware trap name.
  * @input_dev: Input netdevice.
+ * @fa_cookie: Flow action user cookie.
  */
 struct net_dm_hw_metadata {
        const char *trap_group_name;
        const char *trap_name;
        struct net_device *input_dev;
+       const struct flow_action_cookie *fa_cookie;
 };
 
 #if IS_ENABLED(CONFIG_NET_DROP_MONITOR)
index 8bf79a9..66048cc 100644 (file)
@@ -92,6 +92,7 @@ enum net_dm_attr {
        NET_DM_ATTR_HW_TRAP_COUNT,              /* u32 */
        NET_DM_ATTR_SW_DROPS,                   /* flag */
        NET_DM_ATTR_HW_DROPS,                   /* flag */
+       NET_DM_ATTR_FLOW_ACTION_COOKIE,         /* binary */
 
        __NET_DM_ATTR_MAX,
        NET_DM_ATTR_MAX = __NET_DM_ATTR_MAX - 1
index 31700e0..d58c1c4 100644 (file)
@@ -29,6 +29,7 @@
 #include <net/drop_monitor.h>
 #include <net/genetlink.h>
 #include <net/netevent.h>
+#include <net/flow_offload.h>
 
 #include <trace/events/skb.h>
 #include <trace/events/napi.h>
@@ -701,6 +702,13 @@ static void net_dm_packet_work(struct work_struct *work)
 }
 
 static size_t
+net_dm_flow_action_cookie_size(const struct net_dm_hw_metadata *hw_metadata)
+{
+       return hw_metadata->fa_cookie ?
+              nla_total_size(hw_metadata->fa_cookie->cookie_len) : 0;
+}
+
+static size_t
 net_dm_hw_packet_report_size(size_t payload_len,
                             const struct net_dm_hw_metadata *hw_metadata)
 {
@@ -717,6 +725,8 @@ net_dm_hw_packet_report_size(size_t payload_len,
               nla_total_size(strlen(hw_metadata->trap_name) + 1) +
               /* NET_DM_ATTR_IN_PORT */
               net_dm_in_port_size() +
+              /* NET_DM_ATTR_FLOW_ACTION_COOKIE */
+              net_dm_flow_action_cookie_size(hw_metadata) +
               /* NET_DM_ATTR_TIMESTAMP */
               nla_total_size(sizeof(u64)) +
               /* NET_DM_ATTR_ORIG_LEN */
@@ -762,6 +772,12 @@ static int net_dm_hw_packet_report_fill(struct sk_buff *msg,
                        goto nla_put_failure;
        }
 
+       if (hw_metadata->fa_cookie &&
+           nla_put(msg, NET_DM_ATTR_FLOW_ACTION_COOKIE,
+                   hw_metadata->fa_cookie->cookie_len,
+                   hw_metadata->fa_cookie->cookie))
+               goto nla_put_failure;
+
        if (nla_put_u64_64bit(msg, NET_DM_ATTR_TIMESTAMP,
                              ktime_to_ns(skb->tstamp), NET_DM_ATTR_PAD))
                goto nla_put_failure;
@@ -794,11 +810,12 @@ nla_put_failure:
 static struct net_dm_hw_metadata *
 net_dm_hw_metadata_clone(const struct net_dm_hw_metadata *hw_metadata)
 {
+       const struct flow_action_cookie *fa_cookie;
        struct net_dm_hw_metadata *n_hw_metadata;
        const char *trap_group_name;
        const char *trap_name;
 
-       n_hw_metadata = kmalloc(sizeof(*hw_metadata), GFP_ATOMIC);
+       n_hw_metadata = kzalloc(sizeof(*hw_metadata), GFP_ATOMIC);
        if (!n_hw_metadata)
                return NULL;
 
@@ -812,12 +829,25 @@ net_dm_hw_metadata_clone(const struct net_dm_hw_metadata *hw_metadata)
                goto free_trap_group;
        n_hw_metadata->trap_name = trap_name;
 
+       if (hw_metadata->fa_cookie) {
+               size_t cookie_size = sizeof(*fa_cookie) +
+                                    hw_metadata->fa_cookie->cookie_len;
+
+               fa_cookie = kmemdup(hw_metadata->fa_cookie, cookie_size,
+                                   GFP_ATOMIC);
+               if (!fa_cookie)
+                       goto free_trap_name;
+               n_hw_metadata->fa_cookie = fa_cookie;
+       }
+
        n_hw_metadata->input_dev = hw_metadata->input_dev;
        if (n_hw_metadata->input_dev)
                dev_hold(n_hw_metadata->input_dev);
 
        return n_hw_metadata;
 
+free_trap_name:
+       kfree(trap_name);
 free_trap_group:
        kfree(trap_group_name);
 free_hw_metadata:
@@ -830,6 +860,7 @@ net_dm_hw_metadata_free(const struct net_dm_hw_metadata *hw_metadata)
 {
        if (hw_metadata->input_dev)
                dev_put(hw_metadata->input_dev);
+       kfree(hw_metadata->fa_cookie);
        kfree(hw_metadata->trap_name);
        kfree(hw_metadata->trap_group_name);
        kfree(hw_metadata);