/* RSS related */ #define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203 /* query only */ #define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204 /* query and set */
struct ndis_pkt_8021q_info { union { struct {
u32 pri:3; /* User Priority */
u32 cfi:1; /* Canonical Format ID */
u32 vlanid:12; /* VLAN ID */
u32 reserved:16;
};
u32 value;
};
};
/* * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame * within the RNDIS * * The size of this structure is less than 48 bytes and we can now * place this structure in the skb->cb field.
*/ struct hv_netvsc_packet { /* Bookkeeping stuff */
u8 cp_partial; /* partial copy into send buffer */
u8 rmsg_size; /* RNDIS header and PPI size */
u8 page_buf_cnt;
/* * This message is used by the VSC to initialize the channel after the channels * has been opened. This message should never include anything other then * versioning (i.e. this message will be the same for ever).
*/ struct nvsp_message_init {
u32 min_protocol_ver;
u32 max_protocol_ver;
} __packed;
/* * This message is used by the VSP to complete the initialization of the * channel. This message should never include anything other then versioning * (i.e. this message will be the same for ever).
*/ struct nvsp_message_init_complete {
u32 negotiated_protocol_ver;
u32 max_mdl_chain_len;
u32 status;
} __packed;
/* * This message is used by the VSC to send the NDIS version to the VSP. The VSP * can use this information when handling OIDs sent by the VSC.
*/ struct nvsp_1_message_send_ndis_version {
u32 ndis_major_ver;
u32 ndis_minor_ver;
} __packed;
/* * This message is used by the VSC to send a receive buffer to the VSP. The VSP * can then use the receive buffer to send data to the VSC.
*/ struct nvsp_1_message_send_receive_buffer {
u32 gpadl_handle;
u16 id;
} __packed;
/* * This message is used by the VSP to acknowledge a receive buffer send by the * VSC. This message must be sent by the VSP before the VSP uses the receive * buffer.
*/ struct nvsp_1_message_send_receive_buffer_complete {
u32 status;
u32 num_sections;
/* * The receive buffer is split into two parts, a large suballocation * section and a small suballocation section. These sections are then * suballocated by a certain size.
*/
/* * For example, the following break up of the receive buffer has 6 * large suballocations and 10 small suballocations.
*/
/* * This message is sent by the VSC to revoke the receive buffer. After the VSP * completes this transaction, the vsp should never use the receive buffer * again.
*/ struct nvsp_1_message_revoke_receive_buffer {
u16 id;
};
/* * This message is used by the VSC to send a send buffer to the VSP. The VSC * can then use the send buffer to send data to the VSP.
*/ struct nvsp_1_message_send_send_buffer {
u32 gpadl_handle;
u16 id;
} __packed;
/* * This message is used by the VSP to acknowledge a send buffer sent by the * VSC. This message must be sent by the VSP before the VSP uses the sent * buffer.
*/ struct nvsp_1_message_send_send_buffer_complete {
u32 status;
/* * The VSC gets to choose the size of the send buffer and the VSP gets * to choose the sections size of the buffer. This was done to enable * dynamic reconfigurations when the cost of GPA-direct buffers * decreases.
*/
u32 section_size;
} __packed;
/* * This message is sent by the VSC to revoke the send buffer. After the VSP * completes this transaction, the vsp should never use the send buffer again.
*/ struct nvsp_1_message_revoke_send_buffer {
u16 id;
};
/* * This message is used by both the VSP and the VSC to send a RNDIS message to * the opposite channel endpoint.
*/ struct nvsp_1_message_send_rndis_packet { /* * This field is specified by RNDIS. They assume there's two different * channels of communication. However, the Network VSP only has one. * Therefore, the channel travels with the RNDIS packet.
*/
u32 channel_type;
/* * This field is used to send part or all of the data through a send * buffer. This values specifies an index into the send buffer. If the * index is 0xFFFFFFFF, then the send buffer is not being used and all * of the data was sent through other VMBus mechanisms.
*/
u32 send_buf_section_index;
u32 send_buf_section_size;
} __packed;
/* * This message is used by both the VSP and the VSC to complete a RNDIS message * to the opposite channel endpoint. At this point, the initiator of this * message cannot use any resources associated with the original RNDIS packet.
*/ struct nvsp_1_message_send_rndis_packet_complete {
u32 status;
};
union nvsp_1_message_uber { struct nvsp_1_message_send_ndis_version send_ndis_ver;
struct nvsp_5_subchannel_complete {
u32 status;
u32 num_subchannels; /* Actual number of subchannels allocated */
} __packed;
struct nvsp_5_send_indirect_table { /* The number of entries in the send indirection table */
u32 count;
/* The offset of the send indirection table from the beginning of * struct nvsp_message. * The send indirection table tells which channel to put the send * traffic on. Each entry is a channel number.
*/
u32 offset;
} __packed;
union nvsp_all_messages { union nvsp_message_init_uber init_msg; union nvsp_1_message_uber v1_msg; union nvsp_2_message_uber v2_msg; union nvsp_4_message_uber v4_msg; union nvsp_5_message_uber v5_msg; union nvsp_6_message_uber v6_msg;
} __packed;
/* ALL Messages */ struct nvsp_message { struct nvsp_message_header hdr; union nvsp_all_messages msg;
} __packed;
/* Maximum # of contiguous data ranges that can make up a trasmitted packet. * Typically it's the max SKB fragments plus 2 for the rndis packet and the * linear portion of the SKB. But if MAX_SKB_FRAGS is large, the value may * need to be limited to MAX_PAGE_BUFFER_COUNT, which is the max # of entries * in a GPA direct packet sent to netvsp over VMBus.
*/ #if MAX_SKB_FRAGS + 2 < MAX_PAGE_BUFFER_COUNT #define MAX_DATA_RANGES (MAX_SKB_FRAGS + 2) #else #define MAX_DATA_RANGES MAX_PAGE_BUFFER_COUNT #endif
/* XFER PAGE packets can specify a maximum of 375 ranges for NDIS >= 6.0 * and a maximum of 64 ranges for NDIS < 6.0 with no RSC; with RSC, this * limit is raised to 562 (= NVSP_RSC_MAX).
*/ #define NETVSC_MAX_XFER_PAGE_RANGES NVSP_RSC_MAX #define NETVSC_XFER_HEADER_SIZE(rng_cnt) \
(offsetof(struct vmtransfer_page_packet_header, ranges) + \
(rng_cnt) * sizeof(struct vmtransfer_page_range)) #define NETVSC_MAX_PKT_SIZE (NETVSC_XFER_HEADER_SIZE(NETVSC_MAX_XFER_PAGE_RANGES) + \ sizeof(struct nvsp_message) + (sizeof(u32) * VRSS_SEND_TAB_SIZE))
struct multi_recv_comp { struct recv_comp_data *slots;
u32 first; /* first data entry */
u32 next; /* next entry for writing */
};
#define NVSP_RSC_MAX 562 /* Max #RSC frags in a vmbus xfer page pkt */
struct nvsc_rsc { struct ndis_pkt_8021q_info vlan; struct ndis_tcp_ip_checksum_info csum_info;
u32 hash_info;
u8 ppi_flags; /* valid/present bits for the above PPIs */
u8 is_last; /* last RNDIS msg in a vmtransfer_page */
u32 cnt; /* #fragments in an RSC packet */
u32 pktlen; /* Full packet length */ void *data[NVSP_RSC_MAX];
u32 len[NVSP_RSC_MAX];
};
#define NVSC_RSC_VLAN BIT(0) /* valid/present bit for 'vlan' */ #define NVSC_RSC_CSUM_INFO BIT(1) /* valid/present bit for 'csum_info' */ #define NVSC_RSC_HASH_INFO BIT(2) /* valid/present bit for 'hash_info' */
/* State to manage the associated VF interface. */ struct net_device __rcu *vf_netdev; struct netvsc_vf_pcpu_stats __percpu *vf_stats; struct delayed_work vf_takeover; struct delayed_work vfns_work;
/* 1: allocated, serial number is valid. 0: not allocated */
u32 vf_alloc; /* Serial number of the VF to team with */
u32 vf_serial; /* completion variable to confirm vf association */ struct completion vf_add; /* Is the current data path through the VF NIC? */ bool data_path_is_vf;
/* Used to temporarily save the config info across hibernation */ struct netvsc_device_info *saved_netvsc_dev_info;
};
void netvsc_vfns_work(struct work_struct *w);
/* Azure hosts don't support non-TCP port numbers in hashing for fragmented * packets. We can use ethtool to change UDP hash level when necessary.
*/ staticinline u32 netvsc_get_hash(struct sk_buff *skb, conststruct net_device_context *ndc)
{ struct flow_keys flow;
u32 hash, pkt_proto = 0; static u32 hashrnd __read_mostly;
net_get_random_once(&hashrnd, sizeof(hashrnd));
if (!skb_flow_dissect_flow_keys(skb, &flow, 0)) return 0;
switch (flow.basic.ip_proto) { case IPPROTO_TCP: if (flow.basic.n_proto == htons(ETH_P_IP))
pkt_proto = HV_TCP4_L4HASH; elseif (flow.basic.n_proto == htons(ETH_P_IPV6))
pkt_proto = HV_TCP6_L4HASH;
break;
case IPPROTO_UDP: if (flow.basic.n_proto == htons(ETH_P_IP))
pkt_proto = HV_UDP4_L4HASH; elseif (flow.basic.n_proto == htons(ETH_P_IPV6))
pkt_proto = HV_UDP6_L4HASH;
/* Call manager devices only: Information about an address family */ /* supported by the device is appended to the response to NdisInitialize. */ struct rndis_co_address_family {
u32 address_family;
u32 major_ver;
u32 minor_ver;
};
/* * Data message. All Offset fields contain byte offsets from the beginning of * struct rndis_packet. All Length fields are in bytes. VcHandle is set * to 0 for connectionless data, otherwise it contains the VC handle.
*/ struct rndis_packet {
u32 data_offset;
u32 data_len;
u32 oob_data_offset;
u32 oob_data_len;
u32 num_oob_data_elements;
u32 per_pkt_info_offset;
u32 per_pkt_info_len;
u32 vc_handle;
u32 reserved;
};
/* Optional Out of Band data associated with a Data message. */ struct rndis_oobd {
u32 size;
u32 type;
u32 class_info_offset;
};
/* Packet extension field contents associated with a Data message. */ struct rndis_per_packet_info {
u32 size;
u32 type:31;
u32 internal:1;
u32 ppi_offset;
};
/* Total size of all PPI data */ #define NDIS_ALL_PPI_SIZE (NDIS_VLAN_PPI_SIZE + NDIS_CSUM_PPI_SIZE + \
NDIS_LSO_PPI_SIZE + NDIS_HASH_PPI_SIZE)
/* Format of Information buffer passed in a SetRequest for the OID */ /* OID_GEN_RNDIS_CONFIG_PARAMETER. */ struct rndis_config_parameter_info {
u32 parameter_name_offset;
u32 parameter_name_length;
u32 parameter_type;
u32 parameter_value_offset;
u32 parameter_value_length;
};
/* Values for ParameterType in struct rndis_config_parameter_info */ #define RNDIS_CONFIG_PARAM_TYPE_INTEGER 0 #define RNDIS_CONFIG_PARAM_TYPE_STRING 2
/* CONDIS Miniport messages for connection oriented devices */ /* that do not implement a call manager. */
/* Total length of this message, from the beginning */ /* of the struct rndis_message, in bytes. */
u32 msg_len;
/* Actual message */ union rndis_message_container msg;
};
/* Handy macros */
/* get the size of an RNDIS message. Pass in the message type, */ /* struct rndis_set_request, struct rndis_packet for example */ #define RNDIS_MESSAGE_SIZE(msg) \
(sizeof(msg) + (sizeof(struct rndis_message) - \ sizeof(union rndis_message_container)))
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.