Skip to content

Commit

Permalink
Merge branch 'bridge-mrp-Add-support-for-getting-the-status'
Browse files Browse the repository at this point in the history
Horatiu Vultur says:

====================
bridge: mrp: Add support for getting the status

This patch series extends the MRP netlink interface to allow the userspace
daemon to get the status of the MRP instances in the kernel.

v3:
  - remove misleading comment
  - fix to use correctly the RCU

v2:
  - fix sparse warnings
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 2, 2020
2 parents 23212a7 + 36a8e8e commit 9eb6206
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 1 deletion.
17 changes: 17 additions & 0 deletions include/uapi/linux/if_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ enum {
IFLA_BRIDGE_MRP_RING_STATE,
IFLA_BRIDGE_MRP_RING_ROLE,
IFLA_BRIDGE_MRP_START_TEST,
IFLA_BRIDGE_MRP_INFO,
__IFLA_BRIDGE_MRP_MAX,
};

Expand Down Expand Up @@ -228,6 +229,22 @@ enum {

#define IFLA_BRIDGE_MRP_START_TEST_MAX (__IFLA_BRIDGE_MRP_START_TEST_MAX - 1)

enum {
IFLA_BRIDGE_MRP_INFO_UNSPEC,
IFLA_BRIDGE_MRP_INFO_RING_ID,
IFLA_BRIDGE_MRP_INFO_P_IFINDEX,
IFLA_BRIDGE_MRP_INFO_S_IFINDEX,
IFLA_BRIDGE_MRP_INFO_PRIO,
IFLA_BRIDGE_MRP_INFO_RING_STATE,
IFLA_BRIDGE_MRP_INFO_RING_ROLE,
IFLA_BRIDGE_MRP_INFO_TEST_INTERVAL,
IFLA_BRIDGE_MRP_INFO_TEST_MAX_MISS,
IFLA_BRIDGE_MRP_INFO_TEST_MONITOR,
__IFLA_BRIDGE_MRP_INFO_MAX,
};

#define IFLA_BRIDGE_MRP_INFO_MAX (__IFLA_BRIDGE_MRP_INFO_MAX - 1)

struct br_mrp_instance {
__u32 ring_id;
__u32 p_ifindex;
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ enum {
#define RTEXT_FILTER_BRVLAN (1 << 1)
#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)
#define RTEXT_FILTER_SKIP_STATS (1 << 3)
#define RTEXT_FILTER_MRP (1 << 4)

/* End of information exported to user level */

Expand Down
64 changes: 64 additions & 0 deletions net/bridge/br_mrp_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,70 @@ int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
return 0;
}

int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
{
struct nlattr *tb, *mrp_tb;
struct br_mrp *mrp;

mrp_tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP);
if (!mrp_tb)
return -EMSGSIZE;

list_for_each_entry_rcu(mrp, &br->mrp_list, list) {
struct net_bridge_port *p;

tb = nla_nest_start_noflag(skb, IFLA_BRIDGE_MRP_INFO);
if (!tb)
goto nla_info_failure;

if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ID,
mrp->ring_id))
goto nla_put_failure;

p = rcu_dereference(mrp->p_port);
if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_P_IFINDEX,
p->dev->ifindex))
goto nla_put_failure;

p = rcu_dereference(mrp->s_port);
if (p && nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_S_IFINDEX,
p->dev->ifindex))
goto nla_put_failure;

if (nla_put_u16(skb, IFLA_BRIDGE_MRP_INFO_PRIO,
mrp->prio))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_STATE,
mrp->ring_state))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_RING_ROLE,
mrp->ring_role))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_INTERVAL,
mrp->test_interval))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MAX_MISS,
mrp->test_max_miss))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_BRIDGE_MRP_INFO_TEST_MONITOR,
mrp->test_monitor))
goto nla_put_failure;

nla_nest_end(skb, tb);
}
nla_nest_end(skb, mrp_tb);

return 0;

nla_put_failure:
nla_nest_cancel(skb, tb);

nla_info_failure:
nla_nest_cancel(skb, mrp_tb);

return -EMSGSIZE;
}

int br_mrp_port_open(struct net_device *dev, u8 loc)
{
struct net_bridge_port *p;
Expand Down
25 changes: 24 additions & 1 deletion net/bridge/br_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,28 @@ static int br_fill_ifinfo(struct sk_buff *skb,
rcu_read_unlock();
if (err)
goto nla_put_failure;

nla_nest_end(skb, af);
}

if (filter_mask & RTEXT_FILTER_MRP) {
struct nlattr *af;
int err;

if (!br_mrp_enabled(br) || port)
goto done;

af = nla_nest_start_noflag(skb, IFLA_AF_SPEC);
if (!af)
goto nla_put_failure;

rcu_read_lock();
err = br_mrp_fill_info(skb, br);
rcu_read_unlock();

if (err)
goto nla_put_failure;

nla_nest_end(skb, af);
}

Expand Down Expand Up @@ -516,7 +538,8 @@ int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
struct net_bridge_port *port = br_port_get_rtnl(dev);

if (!port && !(filter_mask & RTEXT_FILTER_BRVLAN) &&
!(filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED))
!(filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) &&
!(filter_mask & RTEXT_FILTER_MRP))
return 0;

return br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, nlflags,
Expand Down
7 changes: 7 additions & 0 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,7 @@ int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
bool br_mrp_enabled(struct net_bridge *br);
void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br);
#else
static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
struct nlattr *attr, int cmd,
Expand All @@ -1339,6 +1340,12 @@ static inline void br_mrp_port_del(struct net_bridge *br,
struct net_bridge_port *p)
{
}

static inline int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br)
{
return 0;
}

#endif

/* br_netlink.c */
Expand Down

0 comments on commit 9eb6206

Please sign in to comment.