Skip to content

Commit a785403

Browse files
Nikolay Aleksandrovdavem330
authored andcommitted
bridge: netlink: add support for vlan_filtering attribute
This patch adds the ability to toggle the vlan filtering support via netlink. Since we're already running with rtnl in .changelink() we don't need to take any additional locks. Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent e72ee3e commit a785403

File tree

4 files changed

+33
-7
lines changed

4 files changed

+33
-7
lines changed

include/uapi/linux/if_link.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ enum {
230230
IFLA_BR_AGEING_TIME,
231231
IFLA_BR_STP_STATE,
232232
IFLA_BR_PRIORITY,
233+
IFLA_BR_VLAN_FILTERING,
233234
__IFLA_BR_MAX,
234235
};
235236

net/bridge/br_netlink.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = {
724724
[IFLA_BR_AGEING_TIME] = { .type = NLA_U32 },
725725
[IFLA_BR_STP_STATE] = { .type = NLA_U32 },
726726
[IFLA_BR_PRIORITY] = { .type = NLA_U16 },
727+
[IFLA_BR_VLAN_FILTERING] = { .type = NLA_U8 },
727728
};
728729

729730
static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
@@ -771,6 +772,14 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
771772
br_stp_set_bridge_priority(br, priority);
772773
}
773774

775+
if (data[IFLA_BR_VLAN_FILTERING]) {
776+
u8 vlan_filter = nla_get_u8(data[IFLA_BR_VLAN_FILTERING]);
777+
778+
err = __br_vlan_filter_toggle(br, vlan_filter);
779+
if (err)
780+
return err;
781+
}
782+
774783
return 0;
775784
}
776785

@@ -782,6 +791,7 @@ static size_t br_get_size(const struct net_device *brdev)
782791
nla_total_size(sizeof(u32)) + /* IFLA_BR_AGEING_TIME */
783792
nla_total_size(sizeof(u32)) + /* IFLA_BR_STP_STATE */
784793
nla_total_size(sizeof(u16)) + /* IFLA_BR_PRIORITY */
794+
nla_total_size(sizeof(u8)) + /* IFLA_BR_VLAN_FILTERING */
785795
0;
786796
}
787797

@@ -794,13 +804,15 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
794804
u32 ageing_time = jiffies_to_clock_t(br->ageing_time);
795805
u32 stp_enabled = br->stp_enabled;
796806
u16 priority = (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1];
807+
u8 vlan_enabled = br_vlan_enabled(br);
797808

798809
if (nla_put_u32(skb, IFLA_BR_FORWARD_DELAY, forward_delay) ||
799810
nla_put_u32(skb, IFLA_BR_HELLO_TIME, hello_time) ||
800811
nla_put_u32(skb, IFLA_BR_MAX_AGE, age_time) ||
801812
nla_put_u32(skb, IFLA_BR_AGEING_TIME, ageing_time) ||
802813
nla_put_u32(skb, IFLA_BR_STP_STATE, stp_enabled) ||
803-
nla_put_u16(skb, IFLA_BR_PRIORITY, priority))
814+
nla_put_u16(skb, IFLA_BR_PRIORITY, priority) ||
815+
nla_put_u8(skb, IFLA_BR_VLAN_FILTERING, vlan_enabled))
804816
return -EMSGSIZE;
805817

806818
return 0;

net/bridge/br_private.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ int br_vlan_delete(struct net_bridge *br, u16 vid);
614614
void br_vlan_flush(struct net_bridge *br);
615615
bool br_vlan_find(struct net_bridge *br, u16 vid);
616616
void br_recalculate_fwd_mask(struct net_bridge *br);
617+
int __br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
617618
int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
618619
int br_vlan_set_proto(struct net_bridge *br, unsigned long val);
619620
int br_vlan_init(struct net_bridge *br);
@@ -771,6 +772,12 @@ static inline int br_vlan_enabled(struct net_bridge *br)
771772
{
772773
return 0;
773774
}
775+
776+
static inline int __br_vlan_filter_toggle(struct net_bridge *br,
777+
unsigned long val)
778+
{
779+
return -EOPNOTSUPP;
780+
}
774781
#endif
775782

776783
struct nf_br_ops {

net/bridge/br_vlan.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -468,21 +468,27 @@ void br_recalculate_fwd_mask(struct net_bridge *br)
468468
~(1u << br->group_addr[5]);
469469
}
470470

471-
int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
471+
int __br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
472472
{
473-
if (!rtnl_trylock())
474-
return restart_syscall();
475-
476473
if (br->vlan_enabled == val)
477-
goto unlock;
474+
return 0;
478475

479476
br->vlan_enabled = val;
480477
br_manage_promisc(br);
481478
recalculate_group_addr(br);
482479
br_recalculate_fwd_mask(br);
483480

484-
unlock:
481+
return 0;
482+
}
483+
484+
int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val)
485+
{
486+
if (!rtnl_trylock())
487+
return restart_syscall();
488+
489+
__br_vlan_filter_toggle(br, val);
485490
rtnl_unlock();
491+
486492
return 0;
487493
}
488494

0 commit comments

Comments
 (0)