Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7ac8679 authored by Greg Rose's avatar Greg Rose Committed by Jeff Kirsher
Browse files

rtnetlink: Compute and store minimum ifinfo dump size



The message size allocated for rtnl ifinfo dumps was limited to
a single page.  This is not enough for additional interface info
available with devices that support SR-IOV and caused a bug in
which VF info would not be displayed if more than approximately
40 VFs were created per interface.

Implement a new function pointer for the rtnl_register service that will
calculate the amount of data required for the ifinfo dump and allocate
enough data to satisfy the request.

Signed-off-by: default avatarGreg Rose <gregory.v.rose@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 929dd047
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -148,7 +148,7 @@ static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
				return -EINVAL;
			return netlink_dump_start(nls, skb, nlh,
						  client->cb_table[op].dump,
						  NULL);
						  NULL, 0);
		}
	}

+4 −2
Original line number Diff line number Diff line
@@ -221,7 +221,8 @@ struct netlink_callback {
	int			(*dump)(struct sk_buff * skb,
					struct netlink_callback *cb);
	int			(*done)(struct netlink_callback *cb);
	int			family;
	u16			family;
	u16			min_dump_alloc;
	long			args[6];
};

@@ -259,7 +260,8 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags)
extern int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
			      const struct nlmsghdr *nlh,
			      int (*dump)(struct sk_buff *skb, struct netlink_callback*),
			      int (*done)(struct netlink_callback*));
			      int (*done)(struct netlink_callback*),
			      u16 min_dump_alloc);


#define NL_NONROOT_RECV 0x1
+5 −2
Original line number Diff line number Diff line
@@ -6,11 +6,14 @@

typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *);
typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
typedef u16 (*rtnl_calcit_func)(struct sk_buff *);

extern int	__rtnl_register(int protocol, int msgtype,
				rtnl_doit_func, rtnl_dumpit_func);
				rtnl_doit_func, rtnl_dumpit_func,
				rtnl_calcit_func);
extern void	rtnl_register(int protocol, int msgtype,
			      rtnl_doit_func, rtnl_dumpit_func);
			      rtnl_doit_func, rtnl_dumpit_func,
			      rtnl_calcit_func);
extern int	rtnl_unregister(int protocol, int msgtype);
extern void	rtnl_unregister_all(int protocol);

+10 −5
Original line number Diff line number Diff line
@@ -218,19 +218,24 @@ int __init br_netlink_init(void)
	if (err < 0)
		goto err1;

	err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, br_dump_ifinfo);
	err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL,
			      br_dump_ifinfo, NULL);
	if (err)
		goto err2;
	err = __rtnl_register(PF_BRIDGE, RTM_SETLINK, br_rtm_setlink, NULL);
	err = __rtnl_register(PF_BRIDGE, RTM_SETLINK,
			      br_rtm_setlink, NULL, NULL);
	if (err)
		goto err3;
	err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, br_fdb_add, NULL);
	err = __rtnl_register(PF_BRIDGE, RTM_NEWNEIGH,
			      br_fdb_add, NULL, NULL);
	if (err)
		goto err3;
	err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH, br_fdb_delete, NULL);
	err = __rtnl_register(PF_BRIDGE, RTM_DELNEIGH,
			      br_fdb_delete, NULL, NULL);
	if (err)
		goto err3;
	err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, br_fdb_dump);
	err = __rtnl_register(PF_BRIDGE, RTM_GETNEIGH,
			      NULL, br_fdb_dump, NULL);
	if (err)
		goto err3;

+3 −3
Original line number Diff line number Diff line
@@ -740,9 +740,9 @@ static struct pernet_operations fib_rules_net_ops = {
static int __init fib_rules_init(void)
{
	int err;
	rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL);
	rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL);
	rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule);
	rtnl_register(PF_UNSPEC, RTM_NEWRULE, fib_nl_newrule, NULL, NULL);
	rtnl_register(PF_UNSPEC, RTM_DELRULE, fib_nl_delrule, NULL, NULL);
	rtnl_register(PF_UNSPEC, RTM_GETRULE, NULL, fib_nl_dumprule, NULL);

	err = register_pernet_subsys(&fib_rules_net_ops);
	if (err < 0)
Loading