genl: Add genlmsg_new_unicast() for unicast message allocation
Allocates a new sk_buff large enough to cover the specified payload plus required Netlink headers. Will check receiving socket for memory mapped i/o capability and use it if enabled. Will fall back to non-mapped skb if message size exceeds the frame size of the ring. Signed-of-by: Thomas Graf <tgraf@suug.ch> Reviewed-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
Родитель
663efa3696
Коммит
bb9b18fb55
|
@ -73,6 +73,7 @@ struct genl_family {
|
|||
* @attrs: netlink attributes
|
||||
* @_net: network namespace
|
||||
* @user_ptr: user pointers
|
||||
* @dst_sk: destination socket
|
||||
*/
|
||||
struct genl_info {
|
||||
u32 snd_seq;
|
||||
|
@ -85,6 +86,7 @@ struct genl_info {
|
|||
struct net * _net;
|
||||
#endif
|
||||
void * user_ptr[2];
|
||||
struct sock * dst_sk;
|
||||
};
|
||||
|
||||
static inline struct net *genl_info_net(struct genl_info *info)
|
||||
|
@ -177,6 +179,8 @@ void genl_notify(struct genl_family *family,
|
|||
struct sk_buff *skb, struct net *net, u32 portid,
|
||||
u32 group, struct nlmsghdr *nlh, gfp_t flags);
|
||||
|
||||
struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info,
|
||||
gfp_t flags);
|
||||
void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
|
||||
struct genl_family *family, int flags, u8 cmd);
|
||||
|
||||
|
|
|
@ -453,6 +453,26 @@ int genl_unregister_family(struct genl_family *family)
|
|||
}
|
||||
EXPORT_SYMBOL(genl_unregister_family);
|
||||
|
||||
/**
|
||||
* genlmsg_new_unicast - Allocate generic netlink message for unicast
|
||||
* @payload: size of the message payload
|
||||
* @info: information on destination
|
||||
* @flags: the type of memory to allocate
|
||||
*
|
||||
* Allocates a new sk_buff large enough to cover the specified payload
|
||||
* plus required Netlink headers. Will check receiving socket for
|
||||
* memory mapped i/o capability and use it if enabled. Will fall back
|
||||
* to non-mapped skb if message size exceeds the frame size of the ring.
|
||||
*/
|
||||
struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info,
|
||||
gfp_t flags)
|
||||
{
|
||||
size_t len = nlmsg_total_size(genlmsg_total_size(payload));
|
||||
|
||||
return netlink_alloc_skb(info->dst_sk, len, info->snd_portid, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(genlmsg_new_unicast);
|
||||
|
||||
/**
|
||||
* genlmsg_put - Add generic netlink header to netlink message
|
||||
* @skb: socket buffer holding the message
|
||||
|
@ -593,6 +613,7 @@ static int genl_family_rcv_msg(struct genl_family *family,
|
|||
info.genlhdr = nlmsg_data(nlh);
|
||||
info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
|
||||
info.attrs = attrbuf;
|
||||
info.dst_sk = skb->sk;
|
||||
genl_info_net_set(&info, net);
|
||||
memset(&info.user_ptr, 0, sizeof(info.user_ptr));
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче