Commit 57986617 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

drop_monitor: Allow truncation of dropped packets

When sending dropped packets to user space it is not always necessary to
copy the entire packet as usually only the headers are of interest.

Allow user to specify the truncation length and add the original length
of the packet as additional metadata to the netlink message.

By default no truncation is performed.
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ca30707d
...@@ -75,6 +75,8 @@ enum net_dm_attr { ...@@ -75,6 +75,8 @@ enum net_dm_attr {
NET_DM_ATTR_PROTO, /* u16 */ NET_DM_ATTR_PROTO, /* u16 */
NET_DM_ATTR_PAYLOAD, /* binary */ NET_DM_ATTR_PAYLOAD, /* binary */
NET_DM_ATTR_PAD, NET_DM_ATTR_PAD,
NET_DM_ATTR_TRUNC_LEN, /* u32 */
NET_DM_ATTR_ORIG_LEN, /* u32 */
__NET_DM_ATTR_MAX, __NET_DM_ATTR_MAX,
NET_DM_ATTR_MAX = __NET_DM_ATTR_MAX - 1 NET_DM_ATTR_MAX = __NET_DM_ATTR_MAX - 1
......
...@@ -77,6 +77,7 @@ static unsigned long dm_hw_check_delta = 2*HZ; ...@@ -77,6 +77,7 @@ static unsigned long dm_hw_check_delta = 2*HZ;
static LIST_HEAD(hw_stats_list); static LIST_HEAD(hw_stats_list);
static enum net_dm_alert_mode net_dm_alert_mode = NET_DM_ALERT_MODE_SUMMARY; static enum net_dm_alert_mode net_dm_alert_mode = NET_DM_ALERT_MODE_SUMMARY;
static u32 net_dm_trunc_len;
struct net_dm_alert_ops { struct net_dm_alert_ops {
void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb, void (*kfree_skb_probe)(void *ignore, struct sk_buff *skb,
...@@ -334,6 +335,8 @@ static size_t net_dm_packet_report_size(size_t payload_len) ...@@ -334,6 +335,8 @@ static size_t net_dm_packet_report_size(size_t payload_len)
net_dm_in_port_size() + net_dm_in_port_size() +
/* NET_DM_ATTR_TIMESTAMP */ /* NET_DM_ATTR_TIMESTAMP */
nla_total_size(sizeof(struct timespec)) + nla_total_size(sizeof(struct timespec)) +
/* NET_DM_ATTR_ORIG_LEN */
nla_total_size(sizeof(u32)) +
/* NET_DM_ATTR_PROTO */ /* NET_DM_ATTR_PROTO */
nla_total_size(sizeof(u16)) + nla_total_size(sizeof(u16)) +
/* NET_DM_ATTR_PAYLOAD */ /* NET_DM_ATTR_PAYLOAD */
...@@ -391,6 +394,9 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb, ...@@ -391,6 +394,9 @@ static int net_dm_packet_report_fill(struct sk_buff *msg, struct sk_buff *skb,
nla_put(msg, NET_DM_ATTR_TIMESTAMP, sizeof(ts), &ts)) nla_put(msg, NET_DM_ATTR_TIMESTAMP, sizeof(ts), &ts))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_u32(msg, NET_DM_ATTR_ORIG_LEN, skb->len))
goto nla_put_failure;
if (!payload_len) if (!payload_len)
goto out; goto out;
...@@ -429,6 +435,8 @@ static void net_dm_packet_report(struct sk_buff *skb) ...@@ -429,6 +435,8 @@ static void net_dm_packet_report(struct sk_buff *skb)
/* Ensure packet fits inside a single netlink attribute */ /* Ensure packet fits inside a single netlink attribute */
payload_len = min_t(size_t, skb->len, NET_DM_MAX_PACKET_SIZE); payload_len = min_t(size_t, skb->len, NET_DM_MAX_PACKET_SIZE);
if (net_dm_trunc_len)
payload_len = min_t(size_t, net_dm_trunc_len, payload_len);
msg = nlmsg_new(net_dm_packet_report_size(payload_len), GFP_KERNEL); msg = nlmsg_new(net_dm_packet_report_size(payload_len), GFP_KERNEL);
if (!msg) if (!msg)
...@@ -627,6 +635,14 @@ static int net_dm_alert_mode_set(struct genl_info *info) ...@@ -627,6 +635,14 @@ static int net_dm_alert_mode_set(struct genl_info *info)
return 0; return 0;
} }
static void net_dm_trunc_len_set(struct genl_info *info)
{
if (!info->attrs[NET_DM_ATTR_TRUNC_LEN])
return;
net_dm_trunc_len = nla_get_u32(info->attrs[NET_DM_ATTR_TRUNC_LEN]);
}
static int net_dm_cmd_config(struct sk_buff *skb, static int net_dm_cmd_config(struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
{ {
...@@ -642,6 +658,8 @@ static int net_dm_cmd_config(struct sk_buff *skb, ...@@ -642,6 +658,8 @@ static int net_dm_cmd_config(struct sk_buff *skb,
if (rc) if (rc)
return rc; return rc;
net_dm_trunc_len_set(info);
return 0; return 0;
} }
...@@ -700,6 +718,7 @@ static int dropmon_net_event(struct notifier_block *ev_block, ...@@ -700,6 +718,7 @@ static int dropmon_net_event(struct notifier_block *ev_block,
static const struct nla_policy net_dm_nl_policy[NET_DM_ATTR_MAX + 1] = { static const struct nla_policy net_dm_nl_policy[NET_DM_ATTR_MAX + 1] = {
[NET_DM_ATTR_UNSPEC] = { .strict_start_type = NET_DM_ATTR_UNSPEC + 1 }, [NET_DM_ATTR_UNSPEC] = { .strict_start_type = NET_DM_ATTR_UNSPEC + 1 },
[NET_DM_ATTR_ALERT_MODE] = { .type = NLA_U8 }, [NET_DM_ATTR_ALERT_MODE] = { .type = NLA_U8 },
[NET_DM_ATTR_TRUNC_LEN] = { .type = NLA_U32 },
}; };
static const struct genl_ops dropmon_ops[] = { static const struct genl_ops dropmon_ops[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment