#define VNET_HASH_SIZE 17
+#define VNET_MAX_HEADER_LEN 128
+
+/*
+ A VNET header is the data that needs to be
+ prefaced to an outgoing packet for a specific
+ MAC pair and qualifiers
+*/
+struct v3_vnet_header {
+ // this header is for data that match
+ uint8_t src_mac[ETH_ALEN];
+ uint8_t dst_mac[ETH_ALEN];
+
+ uint8_t src_mac_qual;
+ uint8_t dst_mac_qual;
+
+#define VNET_HEADER_NOMATCH 0 // Could not find a header
+#define VNET_HEADER_NONE 1 // There is no header, send/receive without change
+#define VNET_HEADER_RAW 2 // Prepend the following data on a send, remove this much data on a receive
+#define VNET_HEADER_UDP 3 // Prepend this UDP header and then send this as a UDP packet / dual on receive
+#define VNET_HEADER_TCP 4 // Prepend this TCP header and then send this as a TCP segment / dual on receive
+#define VNET_HEADER_VXLAN 5 // Prepend this UDP header + VXLAN ID / dual on receive
+
+ uint32_t header_type;
+
+ uint32_t header_len;
+ uint8_t header_data[VNET_MAX_HEADER_LEN];
+
+
+} __attribute__((packed));
+
+
struct v3_vnet_route {
uint8_t src_mac[ETH_ALEN];
uint8_t dst_mac[ETH_ALEN];
int src_id;
uint8_t src_type;
+
} __attribute__((packed));
void * priv_data);
int v3_vnet_del_dev(int dev_id);
+int v3_vnet_query_header(uint8_t src_mac[6],
+ uint8_t dest_mac[6],
+ int recv,
+ struct v3_vnet_header *header);
+
#endif
Enable debugging for the VNET Virtio interface
+
config VNET_NIC
bool "Enable VNET Backend Device"
default n
help
Enable debugging for the VNET NIC Device
+config VNET_GUEST_IFACE
+ bool "Enable VNET guest hypercall interface"
+ default n
+ depends on VNET
+ help
+ Allows the guest to query for info, such as headers, from VNET
+
+config DEBUG_VNET_GUEST_IFACE
+ bool "VNET guest hypercall interface debugging"
+ default n
+ depends on VNET_GUEST_IFACE && DEBUG_ON
+ help
+ Enable debugging for the VNET guest hypercall interface
+
config NE2K
bool "NE2K"
vnet_unlock_irqrestore(vnet_state.lock, flags);
}
+
+
+
/* At the end allocate a route_list
* This list will be inserted into the cache so we don't need to free it
*/
return matches;
}
+int v3_vnet_query_header(uint8_t src_mac[6],
+ uint8_t dest_mac[6],
+ int recv, // 0 = send, 1=recv
+ struct v3_vnet_header *header)
+{
+ struct route_list *routes;
+ struct vnet_route_info *r;
+ struct v3_vnet_pkt p;
+
+ p.size=14;
+ p.data=p.header;
+ memcpy(p.header,dest_mac,6);
+ memcpy(p.header+6,src_mac,6);
+ memset(p.header+12,0,2);
+
+ p.src_type = LINK_EDGE;
+ p.src_id = 0;
+
+ memcpy(header->src_mac,src_mac,6);
+ memcpy(header->dst_mac,dest_mac,6);
+
+
+ look_into_cache(&p,&routes);
+
+ if (!routes) {
+ routes = match_route(&p);
+ if (!routes) {
+ PrintError("Cannot match route\n");
+ header->header_type=VNET_HEADER_NOMATCH;
+ header->header_len=0;
+ return -1;
+ } else {
+ add_route_to_cache(&p,routes);
+ }
+ }
+
+ if (routes->num_routes<1) {
+ PrintError("Less than one route\n");
+ header->header_type=VNET_HEADER_NOMATCH;
+ header->header_len=0;
+ return -1;
+ }
+
+ if (routes->num_routes>1) {
+ PrintError("More than one route, building header for the first one only\n");
+ }
+
+ r=routes->routes[0];
+
+ switch (r->route_def.dst_type) {
+ case LINK_EDGE: {
+ // switch based on the link type
+ // for mac-in-udp, we would want to generate a mac, ip, and udp header
+ // direct transmission
+
+ // for now we will say we have no encapsulation
+ //
+ header->header_type=VNET_HEADER_NONE;
+ header->header_len=0;
+ header->src_mac_qual=r->route_def.src_mac_qual;
+ header->dst_mac_qual=r->route_def.dst_mac_qual;
+
+ }
+
+ return 0;
+ break;
+
+
+ case LINK_INTERFACE:
+ // direct transmission
+ // let's guess that it goes to the same interface...
+ header->header_type=VNET_HEADER_NONE;
+ header->header_len=0;
+ header->src_mac_qual=r->route_def.src_mac_qual;
+ header->dst_mac_qual=r->route_def.dst_mac_qual;
+
+ return 0;
+ break;
+
+ default:
+ PrintError("Unknown destination type\n");
+ return -1;
+ break;
+
+ }
+
+}
+
+
+
int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
struct route_list * matched_routes = NULL;