mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
hyperv/hn: Combine per-packet-information parsing.
MFC after: 1 week Sponsored by: Microsoft OSTC
This commit is contained in:
parent
eed7cf8d2d
commit
aa77d82eca
3 changed files with 107 additions and 15 deletions
|
|
@ -1291,7 +1291,7 @@ hv_m_append(struct mbuf *m0, int len, c_caddr_t cp)
|
|||
*/
|
||||
int
|
||||
netvsc_recv(struct hv_vmbus_channel *chan, netvsc_packet *packet,
|
||||
rndis_tcp_ip_csum_info *csum_info,
|
||||
const rndis_tcp_ip_csum_info *csum_info,
|
||||
const struct rndis_hash_info *hash_info,
|
||||
const struct rndis_hash_value *hash_value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1085,7 +1085,7 @@ typedef struct rndismp_rx_bufs_info_ {
|
|||
struct hv_vmbus_channel;
|
||||
|
||||
int netvsc_recv(struct hv_vmbus_channel *chan,
|
||||
netvsc_packet *packet, rndis_tcp_ip_csum_info *csum_info,
|
||||
netvsc_packet *packet, const rndis_tcp_ip_csum_info *csum_info,
|
||||
const struct rndis_hash_info *hash_info,
|
||||
const struct rndis_hash_value *hash_value);
|
||||
void netvsc_channel_rollup(struct hv_vmbus_channel *chan);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,22 @@ __FBSDID("$FreeBSD$");
|
|||
#include "hv_rndis.h"
|
||||
#include "hv_rndis_filter.h"
|
||||
|
||||
struct hv_rf_recvinfo {
|
||||
const ndis_8021q_info *vlan_info;
|
||||
const rndis_tcp_ip_csum_info *csum_info;
|
||||
const struct rndis_hash_info *hash_info;
|
||||
const struct rndis_hash_value *hash_value;
|
||||
};
|
||||
|
||||
#define HV_RF_RECVINFO_VLAN 0x1
|
||||
#define HV_RF_RECVINFO_CSUM 0x2
|
||||
#define HV_RF_RECVINFO_HASHINF 0x4
|
||||
#define HV_RF_RECVINFO_HASHVAL 0x8
|
||||
#define HV_RF_RECVINFO_ALL \
|
||||
(HV_RF_RECVINFO_VLAN | \
|
||||
HV_RF_RECVINFO_CSUM | \
|
||||
HV_RF_RECVINFO_HASHINF | \
|
||||
HV_RF_RECVINFO_HASHVAL)
|
||||
|
||||
/*
|
||||
* Forward declarations
|
||||
|
|
@ -433,6 +449,84 @@ hv_rf_receive_indicate_status(rndis_device *device, rndis_msg *response)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hv_rf_find_recvinfo(const rndis_packet *rpkt, struct hv_rf_recvinfo *info)
|
||||
{
|
||||
const rndis_per_packet_info *ppi;
|
||||
uint32_t mask, len;
|
||||
|
||||
info->vlan_info = NULL;
|
||||
info->csum_info = NULL;
|
||||
info->hash_info = NULL;
|
||||
info->hash_value = NULL;
|
||||
|
||||
if (rpkt->per_pkt_info_offset == 0)
|
||||
return 0;
|
||||
|
||||
ppi = (const rndis_per_packet_info *)
|
||||
((const uint8_t *)rpkt + rpkt->per_pkt_info_offset);
|
||||
len = rpkt->per_pkt_info_length;
|
||||
mask = 0;
|
||||
|
||||
while (len != 0) {
|
||||
const void *ppi_dptr;
|
||||
uint32_t ppi_dlen;
|
||||
|
||||
if (__predict_false(ppi->size < ppi->per_packet_info_offset))
|
||||
return EINVAL;
|
||||
ppi_dlen = ppi->size - ppi->per_packet_info_offset;
|
||||
ppi_dptr = (const uint8_t *)ppi + ppi->per_packet_info_offset;
|
||||
|
||||
switch (ppi->type) {
|
||||
case ieee_8021q_info:
|
||||
if (__predict_false(ppi_dlen < sizeof(ndis_8021q_info)))
|
||||
return EINVAL;
|
||||
info->vlan_info = ppi_dptr;
|
||||
mask |= HV_RF_RECVINFO_VLAN;
|
||||
break;
|
||||
|
||||
case tcpip_chksum_info:
|
||||
if (__predict_false(ppi_dlen <
|
||||
sizeof(rndis_tcp_ip_csum_info)))
|
||||
return EINVAL;
|
||||
info->csum_info = ppi_dptr;
|
||||
mask |= HV_RF_RECVINFO_CSUM;
|
||||
break;
|
||||
|
||||
case nbl_hash_value:
|
||||
if (__predict_false(ppi_dlen <
|
||||
sizeof(struct rndis_hash_value)))
|
||||
return EINVAL;
|
||||
info->hash_value = ppi_dptr;
|
||||
mask |= HV_RF_RECVINFO_HASHVAL;
|
||||
break;
|
||||
|
||||
case nbl_hash_info:
|
||||
if (__predict_false(ppi_dlen <
|
||||
sizeof(struct rndis_hash_info)))
|
||||
return EINVAL;
|
||||
info->hash_info = ppi_dptr;
|
||||
mask |= HV_RF_RECVINFO_HASHINF;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto skip;
|
||||
}
|
||||
|
||||
if (mask == HV_RF_RECVINFO_ALL) {
|
||||
/* All found; done */
|
||||
break;
|
||||
}
|
||||
skip:
|
||||
if (__predict_false(len < ppi->size))
|
||||
return EINVAL;
|
||||
len -= ppi->size;
|
||||
ppi = (const rndis_per_packet_info *)
|
||||
((const uint8_t *)ppi + ppi->size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* RNDIS filter receive data
|
||||
*/
|
||||
|
|
@ -441,12 +535,9 @@ hv_rf_receive_data(rndis_device *device, rndis_msg *message,
|
|||
struct hv_vmbus_channel *chan, netvsc_packet *pkt)
|
||||
{
|
||||
rndis_packet *rndis_pkt;
|
||||
ndis_8021q_info *rppi_vlan_info;
|
||||
uint32_t data_offset;
|
||||
rndis_tcp_ip_csum_info *csum_info = NULL;
|
||||
const struct rndis_hash_info *hash_info;
|
||||
const struct rndis_hash_value *hash_value;
|
||||
device_t dev = device->net_dev->dev->device;
|
||||
struct hv_rf_recvinfo info;
|
||||
|
||||
rndis_pkt = &message->msg.packet;
|
||||
|
||||
|
|
@ -470,17 +561,18 @@ hv_rf_receive_data(rndis_device *device, rndis_msg *message,
|
|||
pkt->tot_data_buf_len = rndis_pkt->data_length;
|
||||
pkt->data = (void *)((unsigned long)pkt->data + data_offset);
|
||||
|
||||
rppi_vlan_info = hv_get_ppi_data(rndis_pkt, ieee_8021q_info);
|
||||
if (rppi_vlan_info) {
|
||||
pkt->vlan_tci = rppi_vlan_info->u1.s1.vlan_id;
|
||||
} else {
|
||||
pkt->vlan_tci = 0;
|
||||
if (hv_rf_find_recvinfo(rndis_pkt, &info)) {
|
||||
pkt->status = nvsp_status_failure;
|
||||
device_printf(dev, "recvinfo parsing failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
csum_info = hv_get_ppi_data(rndis_pkt, tcpip_chksum_info);
|
||||
hash_value = hv_get_ppi_data(rndis_pkt, nbl_hash_value);
|
||||
hash_info = hv_get_ppi_data(rndis_pkt, nbl_hash_info);
|
||||
netvsc_recv(chan, pkt, csum_info, hash_info, hash_value);
|
||||
if (info.vlan_info != NULL)
|
||||
pkt->vlan_tci = info.vlan_info->u1.s1.vlan_id;
|
||||
else
|
||||
pkt->vlan_tci = 0;
|
||||
|
||||
netvsc_recv(chan, pkt, info.csum_info, info.hash_info, info.hash_value);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue