--- /dev/null
+From c8b0c404d347fe35786c2589a56e7da7dd23af6f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 25 Mar 2021 08:56:41 +0700
+Subject: tipc: add extack messages for bearer/media failure
+
+From: Hoang Le <hoang.h.le@dektech.com.au>
+
+[ Upstream commit b83e214b2e04204f1fc674574362061492c37245 ]
+
+Add extack error messages for -EINVAL errors when enabling bearer,
+getting/setting properties for a media/bearer
+
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Hoang Le <hoang.h.le@dektech.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/bearer.c | 50 +++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 40 insertions(+), 10 deletions(-)
+
+diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
+index 2649a0a0d45e..8ab17f0da026 100644
+--- a/net/tipc/bearer.c
++++ b/net/tipc/bearer.c
+@@ -231,7 +231,8 @@ void tipc_bearer_remove_dest(struct net *net, u32 bearer_id, u32 dest)
+ */
+ static int tipc_enable_bearer(struct net *net, const char *name,
+ u32 disc_domain, u32 prio,
+- struct nlattr *attr[])
++ struct nlattr *attr[],
++ struct netlink_ext_ack *extack)
+ {
+ struct tipc_net *tn = tipc_net(net);
+ struct tipc_bearer_names b_names;
+@@ -245,17 +246,20 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+
+ if (!bearer_name_validate(name, &b_names)) {
+ errstr = "illegal name";
++ NL_SET_ERR_MSG(extack, "Illegal name");
+ goto rejected;
+ }
+
+ if (prio > TIPC_MAX_LINK_PRI && prio != TIPC_MEDIA_LINK_PRI) {
+ errstr = "illegal priority";
++ NL_SET_ERR_MSG(extack, "Illegal priority");
+ goto rejected;
+ }
+
+ m = tipc_media_find(b_names.media_name);
+ if (!m) {
+ errstr = "media not registered";
++ NL_SET_ERR_MSG(extack, "Media not registered");
+ goto rejected;
+ }
+
+@@ -269,6 +273,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+ break;
+ if (!strcmp(name, b->name)) {
+ errstr = "already enabled";
++ NL_SET_ERR_MSG(extack, "Already enabled");
+ goto rejected;
+ }
+ bearer_id++;
+@@ -280,6 +285,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+ name, prio);
+ if (prio == TIPC_MIN_LINK_PRI) {
+ errstr = "cannot adjust to lower";
++ NL_SET_ERR_MSG(extack, "Cannot adjust to lower");
+ goto rejected;
+ }
+ pr_warn("Bearer <%s>: trying with adjusted priority\n", name);
+@@ -290,6 +296,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+
+ if (bearer_id >= MAX_BEARERS) {
+ errstr = "max 3 bearers permitted";
++ NL_SET_ERR_MSG(extack, "Max 3 bearers permitted");
+ goto rejected;
+ }
+
+@@ -303,6 +310,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+ if (res) {
+ kfree(b);
+ errstr = "failed to enable media";
++ NL_SET_ERR_MSG(extack, "Failed to enable media");
+ goto rejected;
+ }
+
+@@ -318,6 +326,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+ if (res) {
+ bearer_disable(net, b);
+ errstr = "failed to create discoverer";
++ NL_SET_ERR_MSG(extack, "Failed to create discoverer");
+ goto rejected;
+ }
+
+@@ -795,6 +804,7 @@ int tipc_nl_bearer_get(struct sk_buff *skb, struct genl_info *info)
+ bearer = tipc_bearer_find(net, name);
+ if (!bearer) {
+ err = -EINVAL;
++ NL_SET_ERR_MSG(info->extack, "Bearer not found");
+ goto err_out;
+ }
+
+@@ -834,8 +844,10 @@ int __tipc_nl_bearer_disable(struct sk_buff *skb, struct genl_info *info)
+ name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
+
+ bearer = tipc_bearer_find(net, name);
+- if (!bearer)
++ if (!bearer) {
++ NL_SET_ERR_MSG(info->extack, "Bearer not found");
+ return -EINVAL;
++ }
+
+ bearer_disable(net, bearer);
+
+@@ -893,7 +905,8 @@ int __tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
+ prio = nla_get_u32(props[TIPC_NLA_PROP_PRIO]);
+ }
+
+- return tipc_enable_bearer(net, bearer, domain, prio, attrs);
++ return tipc_enable_bearer(net, bearer, domain, prio, attrs,
++ info->extack);
+ }
+
+ int tipc_nl_bearer_enable(struct sk_buff *skb, struct genl_info *info)
+@@ -932,6 +945,7 @@ int tipc_nl_bearer_add(struct sk_buff *skb, struct genl_info *info)
+ b = tipc_bearer_find(net, name);
+ if (!b) {
+ rtnl_unlock();
++ NL_SET_ERR_MSG(info->extack, "Bearer not found");
+ return -EINVAL;
+ }
+
+@@ -972,8 +986,10 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
+ name = nla_data(attrs[TIPC_NLA_BEARER_NAME]);
+
+ b = tipc_bearer_find(net, name);
+- if (!b)
++ if (!b) {
++ NL_SET_ERR_MSG(info->extack, "Bearer not found");
+ return -EINVAL;
++ }
+
+ if (attrs[TIPC_NLA_BEARER_PROP]) {
+ struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
+@@ -992,12 +1008,18 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
+ if (props[TIPC_NLA_PROP_WIN])
+ b->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
+ if (props[TIPC_NLA_PROP_MTU]) {
+- if (b->media->type_id != TIPC_MEDIA_TYPE_UDP)
++ if (b->media->type_id != TIPC_MEDIA_TYPE_UDP) {
++ NL_SET_ERR_MSG(info->extack,
++ "MTU property is unsupported");
+ return -EINVAL;
++ }
+ #ifdef CONFIG_TIPC_MEDIA_UDP
+ if (tipc_udp_mtu_bad(nla_get_u32
+- (props[TIPC_NLA_PROP_MTU])))
++ (props[TIPC_NLA_PROP_MTU]))) {
++ NL_SET_ERR_MSG(info->extack,
++ "MTU value is out-of-range");
+ return -EINVAL;
++ }
+ b->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]);
+ tipc_node_apply_property(net, b, TIPC_NLA_PROP_MTU);
+ #endif
+@@ -1125,6 +1147,7 @@ int tipc_nl_media_get(struct sk_buff *skb, struct genl_info *info)
+ rtnl_lock();
+ media = tipc_media_find(name);
+ if (!media) {
++ NL_SET_ERR_MSG(info->extack, "Media not found");
+ err = -EINVAL;
+ goto err_out;
+ }
+@@ -1161,9 +1184,10 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
+ name = nla_data(attrs[TIPC_NLA_MEDIA_NAME]);
+
+ m = tipc_media_find(name);
+- if (!m)
++ if (!m) {
++ NL_SET_ERR_MSG(info->extack, "Media not found");
+ return -EINVAL;
+-
++ }
+ if (attrs[TIPC_NLA_MEDIA_PROP]) {
+ struct nlattr *props[TIPC_NLA_PROP_MAX + 1];
+
+@@ -1179,12 +1203,18 @@ int __tipc_nl_media_set(struct sk_buff *skb, struct genl_info *info)
+ if (props[TIPC_NLA_PROP_WIN])
+ m->window = nla_get_u32(props[TIPC_NLA_PROP_WIN]);
+ if (props[TIPC_NLA_PROP_MTU]) {
+- if (m->type_id != TIPC_MEDIA_TYPE_UDP)
++ if (m->type_id != TIPC_MEDIA_TYPE_UDP) {
++ NL_SET_ERR_MSG(info->extack,
++ "MTU property is unsupported");
+ return -EINVAL;
++ }
+ #ifdef CONFIG_TIPC_MEDIA_UDP
+ if (tipc_udp_mtu_bad(nla_get_u32
+- (props[TIPC_NLA_PROP_MTU])))
++ (props[TIPC_NLA_PROP_MTU]))) {
++ NL_SET_ERR_MSG(info->extack,
++ "MTU value is out-of-range");
+ return -EINVAL;
++ }
+ m->mtu = nla_get_u32(props[TIPC_NLA_PROP_MTU]);
+ #endif
+ }
+--
+2.30.2
+
--- /dev/null
+From b2cd22be373a63d086d56637d7f1c8ac409672c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 1 Apr 2021 09:30:48 +0700
+Subject: tipc: fix unique bearer names sanity check
+
+From: Hoang Le <hoang.h.le@dektech.com.au>
+
+[ Upstream commit f20a46c3044c3f75232b3d0e2d09af9b25efaf45 ]
+
+When enabling a bearer by name, we don't sanity check its name with
+higher slot in bearer list. This may have the effect that the name
+of an already enabled bearer bypasses the check.
+
+To fix the above issue, we just perform an extra checking with all
+existing bearers.
+
+Fixes: cb30a63384bc9 ("tipc: refactor function tipc_enable_bearer()")
+Cc: stable@vger.kernel.org
+Acked-by: Jon Maloy <jmaloy@redhat.com>
+Signed-off-by: Hoang Le <hoang.h.le@dektech.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/bearer.c | 46 +++++++++++++++++++++++++++-------------------
+ 1 file changed, 27 insertions(+), 19 deletions(-)
+
+diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
+index 8ab17f0da026..e1006ed4d90a 100644
+--- a/net/tipc/bearer.c
++++ b/net/tipc/bearer.c
+@@ -243,6 +243,7 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+ int bearer_id = 0;
+ int res = -EINVAL;
+ char *errstr = "";
++ u32 i;
+
+ if (!bearer_name_validate(name, &b_names)) {
+ errstr = "illegal name";
+@@ -267,31 +268,38 @@ static int tipc_enable_bearer(struct net *net, const char *name,
+ prio = m->priority;
+
+ /* Check new bearer vs existing ones and find free bearer id if any */
+- while (bearer_id < MAX_BEARERS) {
+- b = rtnl_dereference(tn->bearer_list[bearer_id]);
+- if (!b)
+- break;
++ bearer_id = MAX_BEARERS;
++ i = MAX_BEARERS;
++ while (i-- != 0) {
++ b = rtnl_dereference(tn->bearer_list[i]);
++ if (!b) {
++ bearer_id = i;
++ continue;
++ }
+ if (!strcmp(name, b->name)) {
+ errstr = "already enabled";
+ NL_SET_ERR_MSG(extack, "Already enabled");
+ goto rejected;
+ }
+- bearer_id++;
+- if (b->priority != prio)
+- continue;
+- if (++with_this_prio <= 2)
+- continue;
+- pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
+- name, prio);
+- if (prio == TIPC_MIN_LINK_PRI) {
+- errstr = "cannot adjust to lower";
+- NL_SET_ERR_MSG(extack, "Cannot adjust to lower");
+- goto rejected;
++
++ if (b->priority == prio &&
++ (++with_this_prio > 2)) {
++ pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",
++ name, prio);
++
++ if (prio == TIPC_MIN_LINK_PRI) {
++ errstr = "cannot adjust to lower";
++ NL_SET_ERR_MSG(extack, "Cannot adjust to lower");
++ goto rejected;
++ }
++
++ pr_warn("Bearer <%s>: trying with adjusted priority\n",
++ name);
++ prio--;
++ bearer_id = MAX_BEARERS;
++ i = MAX_BEARERS;
++ with_this_prio = 1;
+ }
+- pr_warn("Bearer <%s>: trying with adjusted priority\n", name);
+- prio--;
+- bearer_id = 0;
+- with_this_prio = 1;
+ }
+
+ if (bearer_id >= MAX_BEARERS) {
+--
+2.30.2
+