NLA_PUT(inst->skb, NFULA_PREFIX, plen, prefix);
if (indev) {
- tmp_uint = htonl(indev->ifindex);
#ifndef CONFIG_BRIDGE_NETFILTER
- NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV, sizeof(tmp_uint),
- &tmp_uint);
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
+ htonl(indev->ifindex));
#else
if (pf == PF_BRIDGE) {
/* Case 1: outdev is physical input device, we need to
* look for bridge group (when called from
* netfilter_bridge) */
- NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV,
- sizeof(tmp_uint), &tmp_uint);
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+ htonl(indev->ifindex));
/* this is the bridge group "brX" */
- tmp_uint = htonl(indev->br_port->br->dev->ifindex);
- NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV,
- sizeof(tmp_uint), &tmp_uint);
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
+ htonl(indev->br_port->br->dev->ifindex));
} else {
/* Case 2: indev is bridge group, we need to look for
* physical device (when called from ipv4) */
- NLA_PUT(inst->skb, NFULA_IFINDEX_INDEV,
- sizeof(tmp_uint), &tmp_uint);
- if (skb->nf_bridge && skb->nf_bridge->physindev) {
- tmp_uint =
- htonl(skb->nf_bridge->physindev->ifindex);
- NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSINDEV,
- sizeof(tmp_uint), &tmp_uint);
- }
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV,
+ htonl(indev->ifindex));
+ if (skb->nf_bridge && skb->nf_bridge->physindev)
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+ htonl(skb->nf_bridge->physindev->ifindex));
}
#endif
}
if (outdev) {
tmp_uint = htonl(outdev->ifindex);
#ifndef CONFIG_BRIDGE_NETFILTER
- NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV, sizeof(tmp_uint),
- &tmp_uint);
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
+ htonl(outdev->ifindex));
#else
if (pf == PF_BRIDGE) {
/* Case 1: outdev is physical output device, we need to
* look for bridge group (when called from
* netfilter_bridge) */
- NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
- sizeof(tmp_uint), &tmp_uint);
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+ htonl(outdev->ifindex));
/* this is the bridge group "brX" */
- tmp_uint = htonl(outdev->br_port->br->dev->ifindex);
- NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
- sizeof(tmp_uint), &tmp_uint);
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
+ htonl(outdev->br_port->br->dev->ifindex));
} else {
/* Case 2: indev is a bridge group, we need to look
* for physical device (when called from ipv4) */
- NLA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
- sizeof(tmp_uint), &tmp_uint);
- if (skb->nf_bridge && skb->nf_bridge->physoutdev) {
- tmp_uint =
- htonl(skb->nf_bridge->physoutdev->ifindex);
- NLA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
- sizeof(tmp_uint), &tmp_uint);
- }
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV,
+ htonl(outdev->ifindex));
+ if (skb->nf_bridge && skb->nf_bridge->physoutdev)
+ NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
+ htonl(skb->nf_bridge->physoutdev->ifindex));
}
#endif
}
- if (skb->mark) {
- tmp_uint = htonl(skb->mark);
- NLA_PUT(inst->skb, NFULA_MARK, sizeof(tmp_uint), &tmp_uint);
- }
+ if (skb->mark)
+ NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark));
if (indev && skb->dev) {
struct nfulnl_msg_packet_hw phw;
read_lock_bh(&skb->sk->sk_callback_lock);
if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
__be32 uid = htonl(skb->sk->sk_socket->file->f_uid);
+ __be32 gid = htonl(skb->sk->sk_socket->file->f_gid);
/* need to unlock here since NLA_PUT may goto */
read_unlock_bh(&skb->sk->sk_callback_lock);
- NLA_PUT(inst->skb, NFULA_UID, sizeof(uid), &uid);
+ NLA_PUT_BE32(inst->skb, NFULA_UID, uid);
+ NLA_PUT_BE32(inst->skb, NFULA_GID, gid);
} else
read_unlock_bh(&skb->sk->sk_callback_lock);
}
/* local sequence number */
- if (inst->flags & NFULNL_CFG_F_SEQ) {
- tmp_uint = htonl(inst->seq++);
- NLA_PUT(inst->skb, NFULA_SEQ, sizeof(tmp_uint), &tmp_uint);
- }
+ if (inst->flags & NFULNL_CFG_F_SEQ)
+ NLA_PUT_BE32(inst->skb, NFULA_SEQ, htonl(inst->seq++));
+
/* global sequence number */
- if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) {
- tmp_uint = htonl(atomic_inc_return(&global_seq));
- NLA_PUT(inst->skb, NFULA_SEQ_GLOBAL, sizeof(tmp_uint), &tmp_uint);
- }
+ if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL)
+ NLA_PUT_BE32(inst->skb, NFULA_SEQ_GLOBAL,
+ htonl(atomic_inc_return(&global_seq)));
if (data_len) {
struct nlattr *nla;
/* FIXME: do we want to make the size calculation conditional based on
* what is actually present? way more branches and checks, but more
* memory efficient... */
- size = NLMSG_ALIGN(sizeof(struct nfgenmsg))
+ size = NLMSG_SPACE(sizeof(struct nfgenmsg))
+ nla_total_size(sizeof(struct nfulnl_msg_packet_hdr))
+ nla_total_size(sizeof(u_int32_t)) /* ifindex */
+ nla_total_size(sizeof(u_int32_t)) /* ifindex */
#endif
+ nla_total_size(sizeof(u_int32_t)) /* mark */
+ nla_total_size(sizeof(u_int32_t)) /* uid */
+ + nla_total_size(sizeof(u_int32_t)) /* gid */
+ nla_total_size(plen) /* prefix */
+ nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
+ nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
u_int16_t group_num = ntohs(nfmsg->res_id);
struct nfulnl_instance *inst;
+ struct nfulnl_msg_config_cmd *cmd = NULL;
int ret = 0;
+ if (nfula[NFULA_CFG_CMD]) {
+ u_int8_t pf = nfmsg->nfgen_family;
+ cmd = nla_data(nfula[NFULA_CFG_CMD]);
+
+ /* Commands without queue context */
+ switch (cmd->command) {
+ case NFULNL_CFG_CMD_PF_BIND:
+ return nf_log_register(pf, &nfulnl_logger);
+ case NFULNL_CFG_CMD_PF_UNBIND:
+ nf_log_unregister_pf(pf);
+ return 0;
+ }
+ }
+
inst = instance_lookup_get(group_num);
if (inst && inst->peer_pid != NETLINK_CB(skb).pid) {
ret = -EPERM;
goto out_put;
}
- if (nfula[NFULA_CFG_CMD]) {
- u_int8_t pf = nfmsg->nfgen_family;
- struct nfulnl_msg_config_cmd *cmd;
-
- cmd = nla_data(nfula[NFULA_CFG_CMD]);
-
+ if (cmd != NULL) {
switch (cmd->command) {
case NFULNL_CFG_CMD_BIND:
if (inst) {
instance_destroy(inst);
goto out;
- case NFULNL_CFG_CMD_PF_BIND:
- ret = nf_log_register(pf, &nfulnl_logger);
- break;
- case NFULNL_CFG_CMD_PF_UNBIND:
- /* This is a bug and a feature. We cannot unregister
- * other handlers, like nfnetlink_inst can */
- nf_log_unregister_pf(pf);
- break;
default:
ret = -ENOTSUPP;
break;
}
if (nfula[NFULA_CFG_TIMEOUT]) {
- __be32 timeout =
- *(__be32 *)nla_data(nfula[NFULA_CFG_TIMEOUT]);
+ __be32 timeout = nla_get_be32(nfula[NFULA_CFG_TIMEOUT]);
if (!inst) {
ret = -ENODEV;
}
if (nfula[NFULA_CFG_NLBUFSIZ]) {
- __be32 nlbufsiz =
- *(__be32 *)nla_data(nfula[NFULA_CFG_NLBUFSIZ]);
+ __be32 nlbufsiz = nla_get_be32(nfula[NFULA_CFG_NLBUFSIZ]);
if (!inst) {
ret = -ENODEV;
}
if (nfula[NFULA_CFG_QTHRESH]) {
- __be32 qthresh =
- *(__be32 *)nla_data(nfula[NFULA_CFG_QTHRESH]);
+ __be32 qthresh = nla_get_be32(nfula[NFULA_CFG_QTHRESH]);
if (!inst) {
ret = -ENODEV;
}
if (nfula[NFULA_CFG_FLAGS]) {
- __be16 flags =
- *(__be16 *)nla_data(nfula[NFULA_CFG_FLAGS]);
+ __be16 flags = nla_get_be16(nfula[NFULA_CFG_FLAGS]);
if (!inst) {
ret = -ENODEV;
}
static void *seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(instances_lock)
{
read_lock_bh(&instances_lock);
return get_idx(seq->private, *pos);
}
static void seq_stop(struct seq_file *s, void *v)
+ __releases(instances_lock)
{
read_unlock_bh(&instances_lock);
}