When I initially implemented this protocol, I disregarded the use of netlink
attribute headers, thinking for my purposes they weren't needed. I've come to
find out that, as I'm starting to work with sending down messages with
associated data (like config messages), the kernel code spits out warnings about
trailing data in a netlink skb that doesn't have an associated header on it. As
such, I'm going to start including attribute headers in my netlink transaction,
and so for completeness, I should likely include them on messages bound from the
kernel to user space. This patch adds that header to the kernel, and bumps the
protocol version accordingly
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = "NET_DM",
.id = GENL_ID_GENERATE,
.hdrsize = 0,
.name = "NET_DM",
.maxattr = NET_DM_CMD_MAX,
};
.maxattr = NET_DM_CMD_MAX,
};
{
size_t al;
struct net_dm_alert_msg *msg;
{
size_t al;
struct net_dm_alert_msg *msg;
al = sizeof(struct net_dm_alert_msg);
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
al = sizeof(struct net_dm_alert_msg);
al += dm_hit_limit * sizeof(struct net_dm_drop_point);
+ al += sizeof(struct nlattr);
+
data->skb = genlmsg_new(al, GFP_KERNEL);
genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
0, NET_DM_CMD_ALERT);
data->skb = genlmsg_new(al, GFP_KERNEL);
genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
0, NET_DM_CMD_ALERT);
- msg = __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_alert_msg));
+ nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
+ msg = nla_data(nla);
memset(msg, 0, al);
atomic_set(&data->dm_hit_count, dm_hit_limit);
}
memset(msg, 0, al);
atomic_set(&data->dm_hit_count, dm_hit_limit);
}
{
struct net_dm_alert_msg *msg;
struct nlmsghdr *nlh;
{
struct net_dm_alert_msg *msg;
struct nlmsghdr *nlh;
int i;
struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
int i;
struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
}
nlh = (struct nlmsghdr *)data->skb->data;
}
nlh = (struct nlmsghdr *)data->skb->data;
- msg = genlmsg_data(nlmsg_data(nlh));
+ nla = genlmsg_data(nlmsg_data(nlh));
+ msg = nla_data(nla);
for (i = 0; i < msg->entries; i++) {
if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {
msg->points[i].count++;
for (i = 0; i < msg->entries; i++) {
if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {
msg->points[i].count++;
* We need to create a new entry
*/
__nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
* We need to create a new entry
*/
__nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
+ nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
msg->points[msg->entries].count = 1;
msg->entries++;
memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
msg->points[msg->entries].count = 1;
msg->entries++;