@@ -65,15 +65,21 @@ static int br_port_fill_attrs(struct sk_buff *skb,
6565 * Create one netlink message for one interface
6666 * Contains port and master info as well as carrier and bridge state.
6767 */
68- static int br_fill_ifinfo (struct sk_buff * skb , const struct net_bridge_port * port ,
69- u32 pid , u32 seq , int event , unsigned int flags )
68+ static int br_fill_ifinfo (struct sk_buff * skb ,
69+ const struct net_bridge_port * port ,
70+ u32 pid , u32 seq , int event , unsigned int flags ,
71+ u32 filter_mask , const struct net_device * dev )
7072{
71- const struct net_bridge * br = port -> br ;
72- const struct net_device * dev = port -> dev ;
73+ const struct net_bridge * br ;
7374 struct ifinfomsg * hdr ;
7475 struct nlmsghdr * nlh ;
7576 u8 operstate = netif_running (dev ) ? dev -> operstate : IF_OPER_DOWN ;
7677
78+ if (port )
79+ br = port -> br ;
80+ else
81+ br = netdev_priv (dev );
82+
7783 br_debug (br , "br_fill_info event %d port %s master %s\n" ,
7884 event , dev -> name , br -> dev -> name );
7985
@@ -99,7 +105,7 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
99105 nla_put_u32 (skb , IFLA_LINK , dev -> iflink )))
100106 goto nla_put_failure ;
101107
102- if (event == RTM_NEWLINK ) {
108+ if (event == RTM_NEWLINK && port ) {
103109 struct nlattr * nest
104110 = nla_nest_start (skb , IFLA_PROTINFO | NLA_F_NESTED );
105111
@@ -108,6 +114,40 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
108114 nla_nest_end (skb , nest );
109115 }
110116
117+ /* Check if the VID information is requested */
118+ if (filter_mask & RTEXT_FILTER_BRVLAN ) {
119+ struct nlattr * af ;
120+ const struct net_port_vlans * pv ;
121+ struct bridge_vlan_info vinfo ;
122+ u16 vid ;
123+
124+ if (port )
125+ pv = nbp_get_vlan_info (port );
126+ else
127+ pv = br_get_vlan_info (br );
128+
129+ if (!pv || bitmap_empty (pv -> vlan_bitmap , BR_VLAN_BITMAP_LEN ))
130+ goto done ;
131+
132+ af = nla_nest_start (skb , IFLA_AF_SPEC );
133+ if (!af )
134+ goto nla_put_failure ;
135+
136+ for (vid = find_first_bit (pv -> vlan_bitmap , BR_VLAN_BITMAP_LEN );
137+ vid < BR_VLAN_BITMAP_LEN ;
138+ vid = find_next_bit (pv -> vlan_bitmap ,
139+ BR_VLAN_BITMAP_LEN , vid + 1 )) {
140+ vinfo .vid = vid ;
141+ vinfo .flags = 0 ;
142+ if (nla_put (skb , IFLA_BRIDGE_VLAN_INFO ,
143+ sizeof (vinfo ), & vinfo ))
144+ goto nla_put_failure ;
145+ }
146+
147+ nla_nest_end (skb , af );
148+ }
149+
150+ done :
111151 return nlmsg_end (skb , nlh );
112152
113153nla_put_failure :
@@ -135,7 +175,7 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
135175 if (skb == NULL )
136176 goto errout ;
137177
138- err = br_fill_ifinfo (skb , port , 0 , 0 , event , 0 );
178+ err = br_fill_ifinfo (skb , port , 0 , 0 , event , 0 , 0 , port -> dev );
139179 if (err < 0 ) {
140180 /* -EMSGSIZE implies BUG in br_nlmsg_size() */
141181 WARN_ON (err == - EMSGSIZE );
@@ -154,16 +194,17 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
154194 * Dump information about all ports, in response to GETLINK
155195 */
156196int br_getlink (struct sk_buff * skb , u32 pid , u32 seq ,
157- struct net_device * dev )
197+ struct net_device * dev , u32 filter_mask )
158198{
159199 int err = 0 ;
160200 struct net_bridge_port * port = br_port_get_rcu (dev );
161201
162- /* not a bridge port */
163- if (!port )
202+ /* not a bridge port and */
203+ if (!port && !( filter_mask & RTEXT_FILTER_BRVLAN ) )
164204 goto out ;
165205
166- err = br_fill_ifinfo (skb , port , pid , seq , RTM_NEWLINK , NLM_F_MULTI );
206+ err = br_fill_ifinfo (skb , port , pid , seq , RTM_NEWLINK , NLM_F_MULTI ,
207+ filter_mask , dev );
167208out :
168209 return err ;
169210}
@@ -395,6 +436,29 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[])
395436 return 0 ;
396437}
397438
439+ static size_t br_get_link_af_size (const struct net_device * dev )
440+ {
441+ struct net_port_vlans * pv ;
442+
443+ if (br_port_exists (dev ))
444+ pv = nbp_get_vlan_info (br_port_get_rcu (dev ));
445+ else if (dev -> priv_flags & IFF_EBRIDGE )
446+ pv = br_get_vlan_info ((struct net_bridge * )netdev_priv (dev ));
447+ else
448+ return 0 ;
449+
450+ if (!pv )
451+ return 0 ;
452+
453+ /* Each VLAN is returned in bridge_vlan_info along with flags */
454+ return pv -> num_vlans * nla_total_size (sizeof (struct bridge_vlan_info ));
455+ }
456+
457+ struct rtnl_af_ops br_af_ops = {
458+ .family = AF_BRIDGE ,
459+ .get_link_af_size = br_get_link_af_size ,
460+ };
461+
398462struct rtnl_link_ops br_link_ops __read_mostly = {
399463 .kind = "bridge" ,
400464 .priv_size = sizeof (struct net_bridge ),
@@ -408,11 +472,18 @@ int __init br_netlink_init(void)
408472 int err ;
409473
410474 br_mdb_init ();
411- err = rtnl_link_register ( & br_link_ops );
475+ err = rtnl_af_register ( & br_af_ops );
412476 if (err )
413477 goto out ;
414478
479+ err = rtnl_link_register (& br_link_ops );
480+ if (err )
481+ goto out_af ;
482+
415483 return 0 ;
484+
485+ out_af :
486+ rtnl_af_unregister (& br_af_ops );
416487out :
417488 br_mdb_uninit ();
418489 return err ;
@@ -421,5 +492,6 @@ int __init br_netlink_init(void)
421492void __exit br_netlink_fini (void )
422493{
423494 br_mdb_uninit ();
495+ rtnl_af_unregister (& br_af_ops );
424496 rtnl_link_unregister (& br_link_ops );
425497}
0 commit comments