/* SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0-or-later) * * vim:set noexpandtab shiftwidth=8 softtabstop=8 fileencoding=utf-8: * * Layer 2 network upstream uapi access library */ #include #include #include #include #include #include #include #include #include #include "net_upstream_api.h" int net_us_clear_master(int fd) { if (ioctl(fd, NET_US_IOC_CLR_MASTER, 0) < 0) { warn("ioctl(NET_US_IOC_CLR_MASTER): failed"); return -1; } return 0; } int net_us_set_master(int fd, int ifindex) { if (ioctl(fd, NET_US_IOC_SET_MASTER, (int32_t) ifindex) < 0) { warn("ioctl(NET_US_IOC_SET_MASTER): failed"); return -1; } return 0; } int net_us_rx_clear_all(int fd) { if (ioctl(fd, NET_US_IOC_RXACT_CLEAR_ALL, NULL) < 0) { warn("ioctl(NET_US_IOC_RXACT_CLEAR_ALL): failed"); return -1; } return 0; } static int net_us_rx_add_mac_passthrough(int fd, uint8_t mac[ETH_ALEN], bool check_dest) { struct net_us_mac_passthru param; memcpy(¶m.mac, mac, ETH_ALEN); param.check_dest = check_dest; if (ioctl(fd, NET_US_IOC_RXACT_ADD_MAC_PASSTHRU, ¶m) < 0) { warn("ioctl(NET_US_IOC_RXACT_ADD_MAC_PASSTHRU): failed"); return -1; } return 0; } int net_us_rx_add_mac_passthrough_src(int fd, uint8_t mac[ETH_ALEN]) { return net_us_rx_add_mac_passthrough(fd, mac, false); } int net_us_rx_add_mac_passthrough_dest(int fd, uint8_t mac[ETH_ALEN]) { return net_us_rx_add_mac_passthrough(fd, mac, true); } int net_us_tx_clear_all(int fd) { if (ioctl(fd, NET_US_IOC_TXACT_CLEAR_ALL, NULL) < 0) { warn("ioctl(NET_US_IOC_TXACT_CLEAR_ALL): failed"); return -1; } return 0; } int net_us_tx_add_vlanprio_map(int fd, int vlan_start, int vlan_end, uint8_t *map, int map_len) { struct net_us_vlan_prio_map arg; if (map_len != 8) return -1; arg.vlan_start = vlan_start; arg.vlan_end = vlan_end; memcpy(&arg.priomap, map, map_len); if (ioctl(fd, NET_US_IOC_TXACT_ADD_VLANPRIO_MAP, &arg) < 0) { warn("ioctl(NET_US_IOC_ADD_VLANPRIO_MAP): failed"); return -1; } return 0; } int net_us_get_ifindex(int fd) { int32_t ifindex; if (ioctl(fd, NET_US_IOC_GET_IFINDEX, &ifindex) < 0) { warn("ioctl(NET_US_IOC_GET_IFINDEX): failed"); return -1; } else if (ifindex <= 0) { warn("bad ifindex %d", ifindex); return -1; } return ifindex; } int net_us_open(void) { int fd = open("/dev/net_us", O_RDWR | O_CLOEXEC); if (fd == -1) { warn("Can't open /dev/net_us"); return -1; } return fd; } void net_us_close(int fd) { if (fd != -1) close(fd); }