diff --git a/include/netlink/route/link/bridge.h b/include/netlink/route/link/bridge.h index 71dcc24..74d0e62 100644 --- a/include/netlink/route/link/bridge.h +++ b/include/netlink/route/link/bridge.h @@ -48,6 +48,9 @@ extern int rtnl_link_bridge_unset_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_set_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_get_flags(struct rtnl_link *); +extern char * rtnl_link_bridge_flags2str(int, char *, size_t); +extern int rtnl_link_bridge_str2flags(const char *); + #ifdef __cplusplus } #endif diff --git a/lib/route/link/bridge.c b/lib/route/link/bridge.c index eb02b22..fcf3272 100644 --- a/lib/route/link/bridge.c +++ b/lib/route/link/bridge.c @@ -451,6 +451,30 @@ int rtnl_link_bridge_get_flags(struct rtnl_link *link) return bd->b_flags; } +static const struct trans_tbl bridge_flags[] = { + __ADD(RTNL_BRIDGE_HAIRPIN_MODE, hairpin_mode) + __ADD(RTNL_BRIDGE_BPDU_GUARD, bpdu_guard) + __ADD(RTNL_BRIDGE_ROOT_BLOCK, root_block) + __ADD(RTNL_BRIDGE_FAST_LEAVE, fast_leave) +}; + +/** + * @name Flag Translation + * @{ + */ + +char *rtnl_link_bridge_flags2str(int flags, char *buf, size_t len) +{ + return __flags2str(flags, buf, len, bridge_flags, ARRAY_SIZE(bridge_flags)); +} + +int rtnl_link_bridge_str2flags(const char *name) +{ + return __str2flags(name, bridge_flags, ARRAY_SIZE(bridge_flags)); +} + +/** @} */ + static struct rtnl_link_af_ops bridge_ops = { .ao_family = AF_BRIDGE, .ao_alloc = &bridge_alloc, diff --git a/python/netlink/route/capi.i b/python/netlink/route/capi.i index d4c4b6a..2d72bd7 100644 --- a/python/netlink/route/capi.i +++ b/python/netlink/route/capi.i @@ -254,6 +254,13 @@ extern int rtnl_link_vxlan_disable_l3miss(struct rtnl_link *); /* */ +enum rtnl_link_bridge_flags { + RTNL_BRIDGE_HAIRPIN_MODE = 0x0001, + RTNL_BRIDGE_BPDU_GUARD = 0x0002, + RTNL_BRIDGE_ROOT_BLOCK = 0x0004, + RTNL_BRIDGE_FAST_LEAVE = 0x0008, +}; + extern int rtnl_link_is_bridge(struct rtnl_link *); extern int rtnl_link_bridge_has_ext_info(struct rtnl_link *); @@ -270,6 +277,9 @@ extern int rtnl_link_bridge_unset_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_set_flags(struct rtnl_link *, unsigned int); extern int rtnl_link_bridge_get_flags(struct rtnl_link *); +extern char * rtnl_link_bridge_flags2str(int, char *, size_t); +extern int rtnl_link_bridge_str2flags(const char *); + /* */ %cstring_output_maxsize(char *buf, size_t len) extern const char *rtnl_link_inet_devconf2str(int, char *buf, size_t len); diff --git a/python/netlink/route/links/bridge.py b/python/netlink/route/links/bridge.py index 09d9334..549b092 100644 --- a/python/netlink/route/links/bridge.py +++ b/python/netlink/route/links/bridge.py @@ -76,6 +76,41 @@ class BRIDGELink(object): raise ValueError() capi.rtnl_link_bridge_set_cost(self._link, int(cost)) + @property + @netlink.nlattr(type=str) + def flags(self): + """ BRIDGE flags + Setting this property will *Not* reset flags to value you supply in + Examples: + link.flags = '+xxx' # add xxx flag + link.flags = 'xxx' # exactly the same + link.flags = '-xxx' # remove xxx flag + link.flags = [ '+xxx', '-yyy' ] # list operation + """ + self.bridge_assert_ext_info() + flags = capi.rtnl_link_bridge_get_flags(self._link) + return capi.rtnl_link_bridge_flags2str(flags, 256)[0].split(',') + + def _set_flag(self, flag): + if flag.startswith('-'): + i = capi.rtnl_link_bridge_str2flags(flag[1:]) + capi.rtnl_link_bridge_unset_flags(self._link, i) + elif flag.startswith('+'): + i = capi.rtnl_link_bridge_str2flags(flag[1:]) + capi.rtnl_link_bridge_set_flags(self._link, i) + else: + i = capi.rtnl_link_bridge_str2flags(flag) + capi.rtnl_link_bridge_set_flags(self._link, i) + + @flags.setter + def flags(self, value): + self.bridge_assert_ext_info() + if type(value) is list: + for flag in value: + self._set_flag(flag) + else: + self._set_flag(value) + def brief(self): return 'bridge-has-ext-info {0}'.format(self._has_ext_info)