From ced8283f90b88bbf7ec9a6b869586b611167394e Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 5 Sep 2014 15:51:29 +0200 Subject: bridge: implement rtnl_link_ops->get_slave_size and rtnl_link_ops->fill_slave_info Allow rtnetlink users to get port info in IFLA_INFO_SLAVE_DATA attr Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/bridge/br_netlink.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'net/bridge/br_netlink.c') diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index cb5fcf62f66..80d23471743 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -461,6 +461,19 @@ static int br_dev_newlink(struct net *src_net, struct net_device *dev, return register_netdevice(dev); } +static int br_port_fill_slave_info(struct sk_buff *skb, + const struct net_device *brdev, + const struct net_device *dev) +{ + return br_port_fill_attrs(skb, br_port_get_rtnl(dev)); +} + +static size_t br_port_get_slave_size(const struct net_device *brdev, + const struct net_device *dev) +{ + return br_port_info_size(); +} + static size_t br_get_link_af_size(const struct net_device *dev) { struct net_port_vlans *pv; @@ -485,12 +498,14 @@ static struct rtnl_af_ops br_af_ops = { }; struct rtnl_link_ops br_link_ops __read_mostly = { - .kind = "bridge", - .priv_size = sizeof(struct net_bridge), - .setup = br_dev_setup, - .validate = br_validate, - .newlink = br_dev_newlink, - .dellink = br_dev_delete, + .kind = "bridge", + .priv_size = sizeof(struct net_bridge), + .setup = br_dev_setup, + .validate = br_validate, + .newlink = br_dev_newlink, + .dellink = br_dev_delete, + .get_slave_size = br_port_get_slave_size, + .fill_slave_info = br_port_fill_slave_info, }; int __init br_netlink_init(void) -- cgit v1.2.3-70-g09d2 From 3ac636b8591c37bb5028814a4ebd41d263b56181 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 5 Sep 2014 15:51:30 +0200 Subject: bridge: implement rtnl_link_ops->slave_changelink Allow rtnetlink users to set port info via IFLA_INFO_SLAVE_DATA attr Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/bridge/br_netlink.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'net/bridge/br_netlink.c') diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 80d23471743..05aeea1222a 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -276,7 +276,7 @@ static int br_afspec(struct net_bridge *br, return err; } -static const struct nla_policy ifla_brport_policy[IFLA_BRPORT_MAX + 1] = { +static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = { [IFLA_BRPORT_STATE] = { .type = NLA_U8 }, [IFLA_BRPORT_COST] = { .type = NLA_U32 }, [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 }, @@ -382,7 +382,7 @@ int br_setlink(struct net_device *dev, struct nlmsghdr *nlh) if (p && protinfo) { if (protinfo->nla_type & NLA_F_NESTED) { err = nla_parse_nested(tb, IFLA_BRPORT_MAX, - protinfo, ifla_brport_policy); + protinfo, br_port_policy); if (err) return err; @@ -461,6 +461,16 @@ static int br_dev_newlink(struct net *src_net, struct net_device *dev, return register_netdevice(dev); } +static int br_port_slave_changelink(struct net_device *brdev, + struct net_device *dev, + struct nlattr *tb[], + struct nlattr *data[]) +{ + if (!data) + return 0; + return br_setport(br_port_get_rtnl(dev), data); +} + static int br_port_fill_slave_info(struct sk_buff *skb, const struct net_device *brdev, const struct net_device *dev) @@ -504,6 +514,10 @@ struct rtnl_link_ops br_link_ops __read_mostly = { .validate = br_validate, .newlink = br_dev_newlink, .dellink = br_dev_delete, + + .slave_maxtype = IFLA_BRPORT_MAX, + .slave_policy = br_port_policy, + .slave_changelink = br_port_slave_changelink, .get_slave_size = br_port_get_slave_size, .fill_slave_info = br_port_fill_slave_info, }; -- cgit v1.2.3-70-g09d2 From e5c3ea5c668033b303e7ac835d7d91da32d97958 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 5 Sep 2014 15:51:31 +0200 Subject: bridge: implement rtnl_link_ops->get_size and rtnl_link_ops->fill_info Allow rtnetlink users to get bridge master info in IFLA_INFO_DATA attr This initial part implements forward_delay, hello_time, max_age options. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- include/uapi/linux/if_link.h | 12 ++++++++++++ net/bridge/br_netlink.c | 25 +++++++++++++++++++++++++ 2 files changed, 37 insertions(+) (limited to 'net/bridge/br_netlink.c') diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index ff957604a72..c80f95f6ee7 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -215,6 +215,18 @@ enum in6_addr_gen_mode { IN6_ADDR_GEN_MODE_NONE, }; +/* Bridge section */ + +enum { + IFLA_BR_UNSPEC, + IFLA_BR_FORWARD_DELAY, + IFLA_BR_HELLO_TIME, + IFLA_BR_MAX_AGE, + __IFLA_BR_MAX, +}; + +#define IFLA_BR_MAX (__IFLA_BR_MAX - 1) + enum { BRIDGE_MODE_UNSPEC, BRIDGE_MODE_HAIRPIN, diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 05aeea1222a..bcac09fe2ac 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -484,6 +484,29 @@ static size_t br_port_get_slave_size(const struct net_device *brdev, return br_port_info_size(); } +static size_t br_get_size(const struct net_device *brdev) +{ + return nla_total_size(sizeof(u32)) + /* IFLA_BR_FORWARD_DELAY */ + nla_total_size(sizeof(u32)) + /* IFLA_BR_HELLO_TIME */ + nla_total_size(sizeof(u32)) + /* IFLA_BR_MAX_AGE */ + 0; +} + +static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev) +{ + struct net_bridge *br = netdev_priv(brdev); + u32 forward_delay = jiffies_to_clock_t(br->forward_delay); + u32 hello_time = jiffies_to_clock_t(br->hello_time); + u32 age_time = jiffies_to_clock_t(br->max_age); + + if (nla_put_u32(skb, IFLA_BR_FORWARD_DELAY, forward_delay) || + nla_put_u32(skb, IFLA_BR_HELLO_TIME, hello_time) || + nla_put_u32(skb, IFLA_BR_MAX_AGE, age_time)) + return -EMSGSIZE; + + return 0; +} + static size_t br_get_link_af_size(const struct net_device *dev) { struct net_port_vlans *pv; @@ -514,6 +537,8 @@ struct rtnl_link_ops br_link_ops __read_mostly = { .validate = br_validate, .newlink = br_dev_newlink, .dellink = br_dev_delete, + .get_size = br_get_size, + .fill_info = br_fill_info, .slave_maxtype = IFLA_BRPORT_MAX, .slave_policy = br_port_policy, -- cgit v1.2.3-70-g09d2 From 13323516172178ff8184855ee4bc66d46fd89619 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Fri, 5 Sep 2014 15:51:32 +0200 Subject: bridge: implement rtnl_link_ops->changelink Allow rtnetlink users to set bridge master info via IFLA_INFO_DATA attr This initial part implements forward_delay, hello_time, max_age options. Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- net/bridge/br_netlink.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'net/bridge/br_netlink.c') diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index bcac09fe2ac..7c97a261afa 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -484,6 +484,42 @@ static size_t br_port_get_slave_size(const struct net_device *brdev, return br_port_info_size(); } +static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = { + [IFLA_BR_FORWARD_DELAY] = { .type = NLA_U32 }, + [IFLA_BR_HELLO_TIME] = { .type = NLA_U32 }, + [IFLA_BR_MAX_AGE] = { .type = NLA_U32 }, +}; + +static int br_changelink(struct net_device *brdev, struct nlattr *tb[], + struct nlattr *data[]) +{ + struct net_bridge *br = netdev_priv(brdev); + int err; + + if (!data) + return 0; + + if (data[IFLA_BR_FORWARD_DELAY]) { + err = br_set_forward_delay(br, nla_get_u32(data[IFLA_BR_FORWARD_DELAY])); + if (err) + return err; + } + + if (data[IFLA_BR_HELLO_TIME]) { + err = br_set_hello_time(br, nla_get_u32(data[IFLA_BR_HELLO_TIME])); + if (err) + return err; + } + + if (data[IFLA_BR_MAX_AGE]) { + err = br_set_max_age(br, nla_get_u32(data[IFLA_BR_MAX_AGE])); + if (err) + return err; + } + + return 0; +} + static size_t br_get_size(const struct net_device *brdev) { return nla_total_size(sizeof(u32)) + /* IFLA_BR_FORWARD_DELAY */ @@ -534,8 +570,11 @@ struct rtnl_link_ops br_link_ops __read_mostly = { .kind = "bridge", .priv_size = sizeof(struct net_bridge), .setup = br_dev_setup, + .maxtype = IFLA_BRPORT_MAX, + .policy = br_policy, .validate = br_validate, .newlink = br_dev_newlink, + .changelink = br_changelink, .dellink = br_dev_delete, .get_size = br_get_size, .fill_info = br_fill_info, -- cgit v1.2.3-70-g09d2