diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 774f68d1a2b3..60a6f4a3c0fb 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -287,17 +287,50 @@ static int tipc_enable_bearer(struct net *net, const char *name, bearer_id = MAX_BEARERS; i = MAX_BEARERS; while (i-- != 0) { + struct net_device *dev; + b = rtnl_dereference(tn->bearer_list[i]); if (!b) { bearer_id = i; continue; } if (!strcmp(name, b->name)) { +duplicate: errstr = "already enabled"; NL_SET_ERR_MSG(extack, "Already enabled"); goto rejected; } + /* udp media can be used together with any media */ + if (b->media->type_id == TIPC_MEDIA_TYPE_UDP || + m->type_id == TIPC_MEDIA_TYPE_UDP) + goto priority; + + dev = __dev_get_by_name(net, b_names.if_name); + + if (!dev) { + res = -ENODEV; + errstr = "no device for the media"; + NL_SET_ERR_MSG(extack, "No device for the media"); + goto rejected; + } + + if (rtnl_dereference(b->media_ptr) == dev) { + char *dev_name = strchr((const char *)b->name, ':') + 1; + + /* Not allow altname of occupied device */ + if (strcmp(dev_name, b_names.if_name) && + b->media->type_id == m->type_id) + goto duplicate; + + /* Not allow eth and ib to attach to the same device */ + errstr = "same dev for different media"; + NL_SET_ERR_MSG(extack, + "Same dev for different media"); + goto rejected; + } + +priority: if (b->priority == prio && (++with_this_prio > 2)) { pr_warn("Bearer <%s>: already 2 bearers with priority %u\n",