if (!__ethtool_get_link_ksettings(dev, &ecmd)) { switch (ecmd.base.speed) { case SPEED_10000: return2; case SPEED_5000: return3; case SPEED_2500: return4; case SPEED_1000: return5; case SPEED_100: return19; case SPEED_10: return100; case SPEED_UNKNOWN: return100; default: if (ecmd.base.speed > SPEED_10000) return1;
}
}
/* Old silly heuristics based on name */ if (!strncmp(dev->name, "lec", 3)) return7;
staticvoid br_port_clear_promisc(struct net_bridge_port *p)
{ int err;
/* Check if the port is already non-promisc or if it doesn't *supportUNICASTfiltering.Withoutunicastfilteringsupport *we'llendupre-enablingpromiscmodeanyway,sojustcheckfor *ithere.
*/ if (!br_promisc_port(p) || !(p->dev->priv_flags & IFF_UNICAST_FLT)) return;
/* Since we'll be clearing the promisc mode, program the port *firstsothatwedon'thaveinterruptionintraffic.
*/
err = br_fdb_sync_static(p->br, p); if (err) return;
/* When a port is added or removed or when certain port flags *change,thisfunctioniscalledtoautomaticallymanage *promiscuitysettingofallthebridgeports.Wearealwayscalled *underRTNLsocanskipusingrcuprimitives.
*/ void br_manage_promisc(struct net_bridge *br)
{ struct net_bridge_port *p; bool set_all = false;
/* If vlan filtering is disabled or bridge interface is placed *intopromiscuousmode,placeallportsinpromiscuousmode.
*/ if ((br->dev->flags & IFF_PROMISC) || !br_vlan_enabled(br->dev))
set_all = true;
list_for_each_entry(p, &br->port_list, list) { if (set_all) {
br_port_set_promisc(p);
} else { /* If the number of auto-ports is <= 1, then all other *portswillhavetheiroutputconfiguration *staticallyspecifiedthroughfdbs.Sinceingress *ontheauto-portbecomesforwarding/egresstoother *portsandegressconfigurationisstaticallyknown, *wecansaythatingressconfigurationofthe *auto-portisalsostaticallyknown. *Thisletsusdisablepromiscuousmodeandwrite *thisconfigtohw.
*/ if ((p->dev->priv_flags & IFF_UNICAST_FLT) &&
(br->auto_cnt == 0 ||
(br->auto_cnt == 1 && br_auto_port(p))))
br_port_clear_promisc(p); else
br_port_set_promisc(p);
}
}
}
/* called with RTNL but without bridge lock */ staticstruct net_bridge_port *new_nbp(struct net_bridge *br, struct net_device *dev)
{ struct net_bridge_port *p; int index, err;
index = find_portno(br); if (index < 0) return ERR_PTR(index);
p = kzalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) return ERR_PTR(-ENOMEM);
res = register_netdevice(dev); if (res)
free_netdev(dev); return res;
}
int br_del_bridge(struct net *net, constchar *name)
{ struct net_device *dev; int ret = 0;
dev = __dev_get_by_name(net, name); if (dev == NULL)
ret = -ENXIO; /* Could not find device */
elseif (!netif_is_bridge_master(dev)) { /* Attempt to delete non bridge device! */
ret = -EPERM;
}
elseif (dev->flags & IFF_UP) { /* Not shutdown yet. */
ret = -EBUSY;
}
else
br_dev_delete(dev, NULL);
return ret;
}
/* MTU of the bridge pseudo-device: ETH_DATA_LEN or the minimum of the ports */ staticint br_mtu_min(conststruct net_bridge *br)
{ conststruct net_bridge_port *p; int ret_mtu = 0;
/* if the bridge MTU was manually configured don't mess with it */ if (br_opt_get(br, BROPT_MTU_SET_BY_USER)) return;
/* change to the minimum MTU and clear the flag which was set by *thebridgendo_change_mtucallback
*/
dev_set_mtu(br->dev, br_mtu_min(br));
br_opt_toggle(br, BROPT_MTU_SET_BY_USER, false);
}
/* No bridging of bridges */ if (dev->netdev_ops->ndo_start_xmit == br_dev_xmit) {
NL_SET_ERR_MSG(extack, "Can not enslave a bridge to a bridge"); return -ELOOP;
}
/* Device has master upper dev */ if (netdev_master_upper_dev_get(dev)) return -EBUSY;
/* No bridging devices that dislike that (e.g. wireless) */ if (dev->priv_flags & IFF_DONT_BRIDGE) {
NL_SET_ERR_MSG(extack, "Device does not allow enslaving to a bridge"); return -EOPNOTSUPP;
}
p = new_nbp(br, dev); if (IS_ERR(p)) return PTR_ERR(p);
nbp_update_port_count(br); if (!br_promisc_port(p) && (p->dev->priv_flags & IFF_UNICAST_FLT)) { /* When updating the port count we also update all ports' *promiscuousmode. *Aportleavingpromiscuousmodenormallygetsthebridge's *fdbsyncedtotheunicastfilter(ifsupported),however, *`br_port_clear_promisc`doesnotdistinguishbetween *non-promiscuousportsand*new*ports,soweneedto *syncexplicitlyhere.
*/
fdb_synced = br_fdb_sync_static(br, p) == 0; if (!fdb_synced)
netdev_err(dev, "failed to sync bridge static fdb addresses to this port\n");
}
if (br_fdb_add_local(br, p, dev->dev_addr, 0))
netdev_err(dev, "failed insert local address bridge forwarding table\n");
if (br->dev->addr_assign_type != NET_ADDR_SET) { /* Ask for permission to use this MAC address now, even if we *don'tendupchoosingitbelow.
*/
err = netif_pre_changeaddr_notify(br->dev, dev->dev_addr,
extack); if (err) goto err6;
}
err = nbp_vlan_init(p, extack); if (err) {
netdev_err(dev, "failed to initialize vlan filtering on this port\n"); goto err6;
}
/* called with RTNL */ int br_del_if(struct net_bridge *br, struct net_device *dev)
{ struct net_bridge_port *p; bool changed_addr;
p = br_port_get_rtnl(dev); if (!p || p->br != br) return -EINVAL;
/* Since more than one interface can be attached to a bridge, *therestillmaybeanalternatepathfornetconsoletouse; *thereforethereisnoreasonforaNETDEV_RELEASEevent.
*/
del_nbp(p);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.