Skip to content

Commit d83b060

Browse files
John Fastabenddavem330
John Fastabend
authored andcommitted
net: add fdb generic dump routine
This adds a generic dump routine drivers can call. It should be sufficient to handle any bridging model that uses the unicast address list. This should be most SR-IOV enabled NICs. v2: return error on nlmsg_put and use -EMSGSIZE instead of -ENOMEM this is inline other usages Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 12a9463 commit d83b060

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

net/core/rtnetlink.c

+84
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,37 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
19801980
rtnl_set_sk_err(net, RTNLGRP_LINK, err);
19811981
}
19821982

1983+
static int nlmsg_populate_fdb_fill(struct sk_buff *skb,
1984+
struct net_device *dev,
1985+
u8 *addr, u32 pid, u32 seq,
1986+
int type, unsigned int flags)
1987+
{
1988+
struct nlmsghdr *nlh;
1989+
struct ndmsg *ndm;
1990+
1991+
nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), NLM_F_MULTI);
1992+
if (!nlh)
1993+
return -EMSGSIZE;
1994+
1995+
ndm = nlmsg_data(nlh);
1996+
ndm->ndm_family = AF_BRIDGE;
1997+
ndm->ndm_pad1 = 0;
1998+
ndm->ndm_pad2 = 0;
1999+
ndm->ndm_flags = flags;
2000+
ndm->ndm_type = 0;
2001+
ndm->ndm_ifindex = dev->ifindex;
2002+
ndm->ndm_state = NUD_PERMANENT;
2003+
2004+
if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr))
2005+
goto nla_put_failure;
2006+
2007+
return nlmsg_end(skb, nlh);
2008+
2009+
nla_put_failure:
2010+
nlmsg_cancel(skb, nlh);
2011+
return -EMSGSIZE;
2012+
}
2013+
19832014
static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
19842015
{
19852016
struct net *net = sock_net(skb->sk);
@@ -2101,6 +2132,59 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
21012132
return err;
21022133
}
21032134

2135+
static int nlmsg_populate_fdb(struct sk_buff *skb,
2136+
struct netlink_callback *cb,
2137+
struct net_device *dev,
2138+
int *idx,
2139+
struct netdev_hw_addr_list *list)
2140+
{
2141+
struct netdev_hw_addr *ha;
2142+
int err;
2143+
u32 pid, seq;
2144+
2145+
pid = NETLINK_CB(cb->skb).pid;
2146+
seq = cb->nlh->nlmsg_seq;
2147+
2148+
list_for_each_entry(ha, &list->list, list) {
2149+
if (*idx < cb->args[0])
2150+
goto skip;
2151+
2152+
err = nlmsg_populate_fdb_fill(skb, dev, ha->addr,
2153+
pid, seq, 0, NTF_SELF);
2154+
if (err < 0)
2155+
return err;
2156+
skip:
2157+
*idx += 1;
2158+
}
2159+
return 0;
2160+
}
2161+
2162+
/**
2163+
* ndo_dflt_fdb_dump: default netdevice operation to dump an FDB table.
2164+
* @nlh: netlink message header
2165+
* @dev: netdevice
2166+
*
2167+
* Default netdevice operation to dump the existing unicast address list.
2168+
* Returns zero on success.
2169+
*/
2170+
int ndo_dflt_fdb_dump(struct sk_buff *skb,
2171+
struct netlink_callback *cb,
2172+
struct net_device *dev,
2173+
int idx)
2174+
{
2175+
int err;
2176+
2177+
netif_addr_lock_bh(dev);
2178+
err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc);
2179+
if (err)
2180+
goto out;
2181+
nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->mc);
2182+
out:
2183+
netif_addr_unlock_bh(dev);
2184+
return idx;
2185+
}
2186+
EXPORT_SYMBOL(ndo_dflt_fdb_dump);
2187+
21042188
static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
21052189
{
21062190
int idx = 0;

0 commit comments

Comments
 (0)