@@ -1980,6 +1980,37 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned int change)
1980
1980
rtnl_set_sk_err (net , RTNLGRP_LINK , err );
1981
1981
}
1982
1982
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
+
1983
2014
static int rtnl_fdb_add (struct sk_buff * skb , struct nlmsghdr * nlh , void * arg )
1984
2015
{
1985
2016
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)
2101
2132
return err ;
2102
2133
}
2103
2134
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
+
2104
2188
static int rtnl_fdb_dump (struct sk_buff * skb , struct netlink_callback * cb )
2105
2189
{
2106
2190
int idx = 0 ;
0 commit comments