net/devlink/port.c
Source file repositories/reference/linux-study-clean/net/devlink/port.c
File Facts
- System
- Linux kernel
- Corpus path
net/devlink/port.c- Extension
.c- Size
- 46198 bytes
- Lines
- 1608
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
devl_internal.h
Detected Declarations
function devlink_port_fn_cap_fillfunction devlink_port_fn_roce_fillfunction devlink_port_fn_migratable_fillfunction devlink_port_fn_ipsec_crypto_fillfunction devlink_port_fn_ipsec_packet_fillfunction devlink_port_fn_caps_fillfunction devlink_port_fn_max_io_eqs_fillfunction devlink_nl_port_handle_fillfunction devlink_nl_port_handle_sizefunction devlink_nl_port_attrs_putfunction devlink_port_fn_hw_addr_fillfunction devlink_port_fn_state_validfunction devlink_port_fn_opstate_validfunction devlink_port_fn_state_fillfunction devlink_port_fn_mig_setfunction devlink_port_fn_roce_setfunction devlink_port_fn_ipsec_crypto_setfunction devlink_port_fn_ipsec_packet_setfunction devlink_port_fn_caps_setfunction devlink_port_fn_max_io_eqs_setfunction devlink_nl_port_function_attrs_putfunction devlink_nl_port_fillfunction devlink_port_notifyfunction devlink_ports_notifyfunction devlink_ports_notify_registerfunction devlink_ports_notify_unregisterfunction devlink_nl_port_get_doitfunction devlink_nl_port_get_dump_onefunction xa_for_each_startfunction devlink_nl_port_get_dumpitfunction devlink_port_type_setfunction devlink_port_function_hw_addr_setfunction devlink_port_fn_state_setfunction devlink_port_function_validatefunction devlink_port_function_setfunction devlink_nl_port_set_doitfunction devlink_nl_port_split_doitfunction devlink_nl_port_unsplit_doitfunction devlink_nl_port_new_doitfunction devlink_nl_port_del_doitfunction devlink_port_type_warnfunction devlink_port_type_should_warnfunction devlink_port_type_warn_schedulefunction devlink_port_type_warn_cancelfunction devlink_port_initfunction devlink_port_finifunction devl_port_register_with_opsfunction devlink_port_register_with_ops
Annotated Snippet
const struct net_device_ops *ops = netdev->netdev_ops;
/* If driver registers devlink port, it should set devlink port
* attributes accordingly so the compat functions are called
* and the original ops are not used.
*/
if (ops->ndo_get_phys_port_name) {
/* Some drivers use the same set of ndos for netdevs
* that have devlink_port registered and also for
* those who don't. Make sure that ndo_get_phys_port_name
* returns -EOPNOTSUPP here in case it is defined.
* Warn if not.
*/
char name[IFNAMSIZ];
int err;
err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
WARN_ON(err != -EOPNOTSUPP);
}
if (ops->ndo_get_port_parent_id) {
/* Some drivers use the same set of ndos for netdevs
* that have devlink_port registered and also for
* those who don't. Make sure that ndo_get_port_parent_id
* returns -EOPNOTSUPP here in case it is defined.
* Warn if not.
*/
struct netdev_phys_item_id ppid;
int err;
err = ops->ndo_get_port_parent_id(netdev, &ppid);
WARN_ON(err != -EOPNOTSUPP);
}
}
static void __devlink_port_type_set(struct devlink_port *devlink_port,
enum devlink_port_type type,
void *type_dev)
{
struct net_device *netdev = type_dev;
ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
if (type == DEVLINK_PORT_TYPE_NOTSET) {
devlink_port_type_warn_schedule(devlink_port);
} else {
devlink_port_type_warn_cancel(devlink_port);
if (type == DEVLINK_PORT_TYPE_ETH && netdev)
devlink_port_type_netdev_checks(devlink_port, netdev);
}
spin_lock_bh(&devlink_port->type_lock);
devlink_port->type = type;
switch (type) {
case DEVLINK_PORT_TYPE_ETH:
devlink_port->type_eth.netdev = netdev;
if (netdev) {
ASSERT_RTNL();
devlink_port->type_eth.ifindex = netdev->ifindex;
BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
sizeof(netdev->name));
strcpy(devlink_port->type_eth.ifname, netdev->name);
}
break;
case DEVLINK_PORT_TYPE_IB:
devlink_port->type_ib.ibdev = type_dev;
break;
default:
break;
}
spin_unlock_bh(&devlink_port->type_lock);
devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
}
/**
* devlink_port_type_eth_set - Set port type to Ethernet
*
* @devlink_port: devlink port
*
* If driver is calling this, most likely it is doing something wrong.
*/
void devlink_port_type_eth_set(struct devlink_port *devlink_port)
{
devl_warn(devlink_port->devlink,
"devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
devlink_port->index);
__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
}
EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
/**
Annotation
- Immediate include surface: `devl_internal.h`.
- Detected declarations: `function devlink_port_fn_cap_fill`, `function devlink_port_fn_roce_fill`, `function devlink_port_fn_migratable_fill`, `function devlink_port_fn_ipsec_crypto_fill`, `function devlink_port_fn_ipsec_packet_fill`, `function devlink_port_fn_caps_fill`, `function devlink_port_fn_max_io_eqs_fill`, `function devlink_nl_port_handle_fill`, `function devlink_nl_port_handle_size`, `function devlink_nl_port_attrs_put`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.