1616#include <net/rtnetlink.h>
1717#include <net/net_namespace.h>
1818#include <net/sock.h>
19+ #include <uapi/linux/if_bridge.h>
1920
2021#include "br_private.h"
2122#include "br_private_stp.h"
@@ -119,10 +120,14 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
119120 */
120121void br_ifinfo_notify (int event , struct net_bridge_port * port )
121122{
122- struct net * net = dev_net ( port -> dev ) ;
123+ struct net * net ;
123124 struct sk_buff * skb ;
124125 int err = - ENOBUFS ;
125126
127+ if (!port )
128+ return ;
129+
130+ net = dev_net (port -> dev );
126131 br_debug (port -> br , "port %u(%s) event %d\n" ,
127132 (unsigned int )port -> port_no , port -> dev -> name , event );
128133
@@ -144,6 +149,7 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
144149 rtnl_set_sk_err (net , RTNLGRP_LINK , err );
145150}
146151
152+
147153/*
148154 * Dump information about all ports, in response to GETLINK
149155 */
@@ -162,6 +168,64 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
162168 return err ;
163169}
164170
171+ const struct nla_policy ifla_br_policy [IFLA_MAX + 1 ] = {
172+ [IFLA_BRIDGE_FLAGS ] = { .type = NLA_U16 },
173+ [IFLA_BRIDGE_MODE ] = { .type = NLA_U16 },
174+ [IFLA_BRIDGE_VLAN_INFO ] = { .type = NLA_BINARY ,
175+ .len = sizeof (struct bridge_vlan_info ), },
176+ };
177+
178+ static int br_afspec (struct net_bridge * br ,
179+ struct net_bridge_port * p ,
180+ struct nlattr * af_spec ,
181+ int cmd )
182+ {
183+ struct nlattr * tb [IFLA_BRIDGE_MAX + 1 ];
184+ int err = 0 ;
185+
186+ err = nla_parse_nested (tb , IFLA_BRIDGE_MAX , af_spec , ifla_br_policy );
187+ if (err )
188+ return err ;
189+
190+ if (tb [IFLA_BRIDGE_VLAN_INFO ]) {
191+ struct bridge_vlan_info * vinfo ;
192+
193+ vinfo = nla_data (tb [IFLA_BRIDGE_VLAN_INFO ]);
194+
195+ if (vinfo -> vid >= VLAN_N_VID )
196+ return - EINVAL ;
197+
198+ switch (cmd ) {
199+ case RTM_SETLINK :
200+ if (p ) {
201+ err = nbp_vlan_add (p , vinfo -> vid );
202+ if (err )
203+ break ;
204+
205+ if (vinfo -> flags & BRIDGE_VLAN_INFO_MASTER )
206+ err = br_vlan_add (p -> br , vinfo -> vid );
207+ } else
208+ err = br_vlan_add (br , vinfo -> vid );
209+
210+ if (err )
211+ break ;
212+
213+ break ;
214+
215+ case RTM_DELLINK :
216+ if (p ) {
217+ nbp_vlan_delete (p , vinfo -> vid );
218+ if (vinfo -> flags & BRIDGE_VLAN_INFO_MASTER )
219+ br_vlan_delete (p -> br , vinfo -> vid );
220+ } else
221+ br_vlan_delete (br , vinfo -> vid );
222+ break ;
223+ }
224+ }
225+
226+ return err ;
227+ }
228+
165229static const struct nla_policy ifla_brport_policy [IFLA_BRPORT_MAX + 1 ] = {
166230 [IFLA_BRPORT_STATE ] = { .type = NLA_U8 },
167231 [IFLA_BRPORT_COST ] = { .type = NLA_U32 },
@@ -241,45 +305,84 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
241305{
242306 struct ifinfomsg * ifm ;
243307 struct nlattr * protinfo ;
308+ struct nlattr * afspec ;
244309 struct net_bridge_port * p ;
245310 struct nlattr * tb [IFLA_BRPORT_MAX + 1 ];
246311 int err ;
247312
248313 ifm = nlmsg_data (nlh );
249314
250315 protinfo = nlmsg_find_attr (nlh , sizeof (* ifm ), IFLA_PROTINFO );
251- if (!protinfo )
316+ afspec = nlmsg_find_attr (nlh , sizeof (* ifm ), IFLA_AF_SPEC );
317+ if (!protinfo && !afspec )
252318 return 0 ;
253319
254320 p = br_port_get_rtnl (dev );
255- if (!p )
321+ /* We want to accept dev as bridge itself if the AF_SPEC
322+ * is set to see if someone is setting vlan info on the brigde
323+ */
324+ if (!p && ((dev -> priv_flags & IFF_EBRIDGE ) && !afspec ))
256325 return - EINVAL ;
257326
258- if (protinfo -> nla_type & NLA_F_NESTED ) {
259- err = nla_parse_nested (tb , IFLA_BRPORT_MAX ,
260- protinfo , ifla_brport_policy );
327+ if (p && protinfo ) {
328+ if (protinfo -> nla_type & NLA_F_NESTED ) {
329+ err = nla_parse_nested (tb , IFLA_BRPORT_MAX ,
330+ protinfo , ifla_brport_policy );
331+ if (err )
332+ return err ;
333+
334+ spin_lock_bh (& p -> br -> lock );
335+ err = br_setport (p , tb );
336+ spin_unlock_bh (& p -> br -> lock );
337+ } else {
338+ /* Binary compatability with old RSTP */
339+ if (nla_len (protinfo ) < sizeof (u8 ))
340+ return - EINVAL ;
341+
342+ spin_lock_bh (& p -> br -> lock );
343+ err = br_set_port_state (p , nla_get_u8 (protinfo ));
344+ spin_unlock_bh (& p -> br -> lock );
345+ }
261346 if (err )
262- return err ;
263-
264- spin_lock_bh (& p -> br -> lock );
265- err = br_setport (p , tb );
266- spin_unlock_bh (& p -> br -> lock );
267- } else {
268- /* Binary compatability with old RSTP */
269- if (nla_len (protinfo ) < sizeof (u8 ))
270- return - EINVAL ;
347+ goto out ;
348+ }
271349
272- spin_lock_bh ( & p -> br -> lock );
273- err = br_set_port_state ( p , nla_get_u8 ( protinfo ));
274- spin_unlock_bh ( & p -> br -> lock );
350+ if ( afspec ) {
351+ err = br_afspec (( struct net_bridge * ) netdev_priv ( dev ), p ,
352+ afspec , RTM_SETLINK );
275353 }
276354
277355 if (err == 0 )
278356 br_ifinfo_notify (RTM_NEWLINK , p );
279357
358+ out :
280359 return err ;
281360}
282361
362+ /* Delete port information */
363+ int br_dellink (struct net_device * dev , struct nlmsghdr * nlh )
364+ {
365+ struct ifinfomsg * ifm ;
366+ struct nlattr * afspec ;
367+ struct net_bridge_port * p ;
368+ int err ;
369+
370+ ifm = nlmsg_data (nlh );
371+
372+ afspec = nlmsg_find_attr (nlh , sizeof (* ifm ), IFLA_AF_SPEC );
373+ if (!afspec )
374+ return 0 ;
375+
376+ p = br_port_get_rtnl (dev );
377+ /* We want to accept dev as bridge itself as well */
378+ if (!p && !(dev -> priv_flags & IFF_EBRIDGE ))
379+ return - EINVAL ;
380+
381+ err = br_afspec ((struct net_bridge * )netdev_priv (dev ), p ,
382+ afspec , RTM_DELLINK );
383+
384+ return err ;
385+ }
283386static int br_validate (struct nlattr * tb [], struct nlattr * data [])
284387{
285388 if (tb [IFLA_ADDRESS ]) {
0 commit comments