[PATCH] route/link nested bridge attribute

Tobias Jungel tobias.jungel at bisdn.de
Wed Nov 25 00:24:19 PST 2015


On Di, 2015-11-24 at 12:44 -0700, David Ahern wrote:
> Hi Tobias:
> 
> Someone in my company has an alternative solution to this that I 
> recently ported to top of tree; the patches have more functionality
> than 
> you provide here. I'll send those out today.

Hi David,

sounds great, I will check your patches today. This was just a first
shot to retrieve the vlans, so even better if you support more than
this.

> 
> more below
> 
> 
> On 11/24/15 6:50 AM, Tobias Jungel wrote:
> > Modern kernels support vlan filtering on bridges. This patch stores
> > configured vlan ids on bridge interfaces in struct bridge_data.
> > Furthermore vlan ids are accessible via
> > rtnl_link_bridge_get_vlan_info.
> > 
> > The vlan ids are currently stored in the same way as they are sent
> > from
> > the kernel (i.e. in struct bridge_vlan_info).
> > 
> > Signed-off-by: Tobias Jungel <tobias.jungel at bisdn.de>
> > ---
> >   include/linux-private/linux/if_bridge.h | 14 +++++
> >   include/netlink/route/link/bridge.h     |  4 ++
> >   lib/route/link.c                        |  7 ++-
> >   lib/route/link/bridge.c                 | 90
> > +++++++++++++++++++++++++++++----
> >   libnl-route-3.sym                       |  1 +
> >   5 files changed, 106 insertions(+), 10 deletions(-)
> > 
> > diff --git a/include/linux-private/linux/if_bridge.h
> > b/include/linux-private/linux/if_bridge.h
> > index 5db2975..cfe7d12 100644
> > --- a/include/linux-private/linux/if_bridge.h
> > +++ b/include/linux-private/linux/if_bridge.h
> > @@ -103,20 +103,34 @@ struct __fdb_entry {
> > 
> >   #define BRIDGE_MODE_VEB		0	/* Default
> > loopback mode */
> >   #define BRIDGE_MODE_VEPA	1	/* 802.1Qbg defined VEPA
> > mode */
> > +#define BRIDGE_MODE_UNDEF	0xFFFF  /* mode undefined */
> > 
> >   /* Bridge management nested attributes
> >    * [IFLA_AF_SPEC] = {
> >    *     [IFLA_BRIDGE_FLAGS]
> >    *     [IFLA_BRIDGE_MODE]
> > + *     [IFLA_BRIDGE_VLAN_INFO]
> >    * }
> >    */
> >   enum {
> >   	IFLA_BRIDGE_FLAGS,
> >   	IFLA_BRIDGE_MODE,
> > +	IFLA_BRIDGE_VLAN_INFO,
> >   	__IFLA_BRIDGE_MAX,
> >   };
> >   #define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
> > 
> > +#define BRIDGE_VLAN_INFO_MASTER	(1<<0)	/* Operate on
> > Bridge device as well */
> > +#define BRIDGE_VLAN_INFO_PVID	(1<<1)	/* VLAN is
> > PVID, ingress untagged */
> > +#define BRIDGE_VLAN_INFO_UNTAGGED	(1<<2)	/* VLAN
> > egresses untagged */
> > +#define BRIDGE_VLAN_INFO_RANGE_BEGIN	(1<<3) /* VLAN is
> > start of vlan range */
> > +#define BRIDGE_VLAN_INFO_RANGE_END	(1<<4) /* VLAN is end of
> > vlan range */
> > +
> > +struct bridge_vlan_info {
> > +	__u16 flags;
> > +	__u16 vid;
> > +};
> > +
> >   /* Bridge multicast database attributes
> >    * [MDBA_MDB] = {
> >    *     [MDBA_MDB_ENTRY] = {
> > diff --git a/include/netlink/route/link/bridge.h
> > b/include/netlink/route/link/bridge.h
> > index 16a4505..c04a3e2 100644
> > --- a/include/netlink/route/link/bridge.h
> > +++ b/include/netlink/route/link/bridge.h
> > @@ -14,6 +14,7 @@
> > 
> >   #include <netlink/netlink.h>
> >   #include <netlink/route/link.h>
> > +#include <linux/if_bridge.h>
> > 
> >   #ifdef __cplusplus
> >   extern "C" {
> > @@ -52,6 +53,9 @@ extern char * rtnl_link_bridge_flags2str(int,
> > char *, size_t);
> >   extern int	rtnl_link_bridge_str2flags(const char *);
> > 
> >   extern int	rtnl_link_bridge_add(struct nl_sock *sk, const
> > char *name);
> > +
> > +extern struct bridge_vlan_info
> > *rtnl_link_bridge_get_vlan_info(struct rtnl_link *, int *);
> > +
> >   #ifdef __cplusplus
> >   }
> >   #endif
> > diff --git a/lib/route/link.c b/lib/route/link.c
> > index cfe3779..01bd9ff 100644
> > --- a/lib/route/link.c
> > +++ b/lib/route/link.c
> > @@ -604,6 +604,12 @@ static int link_msg_parser(struct nl_cache_ops
> > *ops, struct sockaddr_nl *who,
> >   		struct nlattr *af_attr;
> >   		int remaining;
> > 
> > +		if (AF_BRIDGE == family && af_ops && af_ops-
> > >ao_parse_af) {
> > +			err = af_ops->ao_parse_af(link,
> > tb[IFLA_AF_SPEC], link->l_af_data[family]);
> > +			if (err < 0)
> > +				goto errout;
> > +		}
> > +
> 
> This is going to drop down and parse IFLA_AF_SPEC again which is not 
> what you want for AF_BRIDGE.

Though I am not yet sure, what you mean here. Maybe your patches will
give me some insight.

/Tobi

> 
> >   		nla_for_each_nested(af_attr, tb[IFLA_AF_SPEC],
> > remaining) {
> >   			af_ops = af_lookup_and_alloc(link,
> > nla_type(af_attr));
> >   			if (af_ops && af_ops->ao_parse_af) {
> 
> David
> 



More information about the libnl mailing list