[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