| /* |
| * Copyright 2018, Data61 |
| * Commonwealth Scientific and Industrial Research Organisation (CSIRO) |
| * ABN 41 687 119 230. |
| * |
| * This software may be distributed and modified according to the terms of |
| * the GNU General Public License version 2. Note that NO WARRANTY is provided. |
| * See "LICENSE_GPLv2.txt" for details. |
| * |
| * @TAG(DATA61_GPL) |
| */ |
| |
| #pragma once |
| |
| #include <stdint.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdbool.h> |
| |
| #include <net/ethernet.h> |
| |
| #include <virtqueue.h> |
| |
| /* TODO: Need to introduce or paramterise this variable into the |
| * build system |
| */ |
| #define VSWITCH_NUM_NODES (4) |
| /* MAC address print format*/ |
| #define PR_MAC802_ADDR "%x:%x:%x:%x:%x:%x" |
| /* Expects a *pointer* to a struct ether_addr */ |
| #define PR_MAC802_ADDR_ARGS(a) (a)->ether_addr_octet[0], \ |
| (a)->ether_addr_octet[1], \ |
| (a)->ether_addr_octet[2], \ |
| (a)->ether_addr_octet[3], \ |
| (a)->ether_addr_octet[4], \ |
| (a)->ether_addr_octet[5] |
| |
| /* |
| * Represents the virtqueues used in a given link between |
| * two nodes. |
| */ |
| typedef struct vswitch_virtqueues_ { |
| virtqueue_driver_t *send_queue; |
| virtqueue_device_t *recv_queue; |
| } vswitch_virtqueues_t; |
| |
| extern struct ether_addr null_macaddr, bcast_macaddr; |
| |
| static inline bool |
| mac802_addr_eq(struct ether_addr *addr0, |
| struct ether_addr *addr1) |
| { |
| for (int i = 0; i < ETH_ALEN; i++) { |
| if (addr0->ether_addr_octet[i] != addr1->ether_addr_octet[i]) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| static inline bool |
| mac802_addr_eq_bcast(struct ether_addr *addr) |
| { |
| return mac802_addr_eq(addr, &bcast_macaddr); |
| } |
| |
| typedef struct vswitch_node_ { |
| struct ether_addr addr; |
| vswitch_virtqueues_t virtqueues; |
| } vswitch_node_t; |
| |
| /* |
| * Each component participating in a vswitch topology should have a |
| * MAC address assigned to them. It is expected during the initialisation of |
| * these nodes they will call "vswitch_connect()" to register the |
| * MAC address of the other nodes it is linked to. This will inturn |
| * populate the vswitch_t data structure. |
| * |
| * Furthermore, each node is expected to have a send and recieve |
| * virtqueue for each destination node it has connection to. |
| */ |
| typedef struct vswitch_ { |
| int n_connected; |
| vswitch_node_t nodes[VSWITCH_NUM_NODES]; |
| } vswitch_t; |
| |
| /** Initialize an instance of this library |
| * @param lib Uninitialized handle for a prospective instance of this library. |
| * @return 0 on success. |
| */ |
| int vswitch_init(vswitch_t *lib); |
| |
| /** Initializes metadata to track a destination node connected to the VSWITCH |
| * bcast domain. |
| * |
| * During initialization of each component it is expected to |
| * call this function to register the MAC address and virtqueues of all |
| * the other nodes it is connected to. |
| * |
| * @param lib An initialized handle an instance of this library. |
| * @param guest_macaddr A pointer to a mac address for the Guest VM being |
| * registered. |
| * @param send_virtqueue An initialized handle to a send virtqueue for |
| * the destination being registered. |
| * @param recv_virtqueue An initialized handle to a recieve virtqueue for |
| * the destination being registered. |
| */ |
| int vswitch_connect(vswitch_t *lib, |
| struct ether_addr *guest_macaddr, |
| virtqueue_driver_t *send_virtqueue, |
| virtqueue_device_t *recv_virtqueue); |
| |
| /** Checks to see if a destination with the MAC address "mac" has been registered with |
| * the library. |
| * |
| * @param lib Initialized instance of this library. |
| * @param mac Mac address of the destination to be looked up. |
| * @return Positive integer if the specified MAC address has been registered. |
| * Negative integer if not. |
| */ |
| int vswitch_get_destnode_index_by_macaddr(vswitch_t *lib, |
| struct ether_addr *mac); |
| |
| /** Used to iterate through all the registered destinations indiscriminately. |
| * @param lib Initialized instance of this library. |
| * @param index Positive integer from 0 to VSWITCH_NUM_NODES. |
| * @return NULL if an invalid index is supplied. Non-NULL if a valid index is |
| * supplied. |
| */ |
| vswitch_node_t *vswitch_get_destnode_by_index(vswitch_t *lib, |
| size_t index); |
| |
| static inline vswitch_node_t * |
| vswitch_get_destnode_by_macaddr(vswitch_t *lib, |
| struct ether_addr *mac) |
| { |
| int idx = vswitch_get_destnode_index_by_macaddr(lib, mac); |
| if (idx < 0) { |
| return NULL; |
| } |
| |
| return vswitch_get_destnode_by_index(lib, idx); |
| } |