const void *ll_dest;
const void *ll_source;
uint16_t net_proto;
+ unsigned int flags;
size_t ll_hlen;
struct net_protocol *net_protocol;
unsigned int prottype;
/* Strip link-layer header */
ll_protocol = pxe_netdev->ll_protocol;
if ( ( rc = ll_protocol->pull ( pxe_netdev, iobuf, &ll_dest,
- &ll_source, &net_proto )) !=0){
+ &ll_source, &net_proto,
+ &flags ) ) != 0 ) {
/* Assume unknown net_proto and no ll_source */
net_proto = 0;
ll_source = NULL;
undi_isr->Frame.segment = rm_ds;
undi_isr->Frame.offset = __from_data16 ( basemem_packet );
undi_isr->ProtType = prottype;
- if ( memcmp ( ll_dest, pxe_netdev->ll_addr,
- ll_protocol->ll_addr_len ) == 0 ) {
- undi_isr->PktType = P_DIRECTED;
- } else if ( memcmp ( ll_dest, pxe_netdev->ll_broadcast,
- ll_protocol->ll_addr_len ) == 0 ) {
+ if ( flags & LL_BROADCAST ) {
undi_isr->PktType = P_BROADCAST;
- } else {
+ } else if ( flags & LL_MULTICAST ) {
undi_isr->PktType = P_MULTICAST;
+ } else {
+ undi_isr->PktType = P_DIRECTED;
}
DBGC2 ( &pxenv_undi_isr, " %04x:%04x+%x(%x) %s hlen %d",
undi_isr->Frame.segment, undi_isr->Frame.offset,
* @ret ll_dest Link-layer destination address
* @ret ll_source Source link-layer address
* @ret net_proto Network-layer protocol, in network-byte order
+ * @ret flags Packet flags
* @ret rc Return status code
*/
static int ipoib_pull ( struct net_device *netdev,
struct io_buffer *iobuf, const void **ll_dest,
- const void **ll_source, uint16_t *net_proto ) {
+ const void **ll_source, uint16_t *net_proto,
+ unsigned int *flags ) {
struct ipoib_device *ipoib = netdev->priv;
struct ipoib_hdr *ipoib_hdr = iobuf->data;
struct ipoib_peer *dest;
*ll_dest = ( dest ? &dest->mac : &ipoib->broadcast );
*ll_source = ( source ? &source->mac : &ipoib->broadcast );
*net_proto = ipoib_hdr->proto;
+ *flags = ( ( *ll_dest == &ipoib->broadcast ) ? LL_BROADCAST : 0 );
return 0;
}
/**
* Process received packet
*
- * @v iobuf I/O buffer
- * @v netdev Network device
- * @v ll_dest Link-layer destination address
- * @v ll_source Link-layer source address
+ * @v iobuf I/O buffer
+ * @v netdev Network device
+ * @v ll_dest Link-layer destination address
+ * @v ll_source Link-layer source address
+ * @v flags Packet flags
+ * @ret rc Return status code
*
* This method takes ownership of the I/O buffer.
*/
int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev,
- const void *ll_dest, const void *ll_source );
+ const void *ll_dest, const void *ll_source,
+ unsigned int flags );
/**
* Transcribe network-layer address
*
- * @v net_addr Network-layer address
- * @ret string Human-readable transcription of address
+ * @v net_addr Network-layer address
+ * @ret string Human-readable transcription of address
*
* This method should convert the network-layer address into a
* human-readable format (e.g. dotted quad notation for IPv4).
uint8_t net_addr_len;
};
+/** Packet is a multicast (including broadcast) packet */
+#define LL_MULTICAST 0x0001
+
+/** Packet is a broadcast packet */
+#define LL_BROADCAST 0x0002
+
/**
* A link-layer protocol
*
* @ret ll_dest Link-layer destination address
* @ret ll_source Source link-layer address
* @ret net_proto Network-layer protocol, in network-byte order
+ * @ret flags Packet flags
* @ret rc Return status code
*/
int ( * pull ) ( struct net_device *netdev, struct io_buffer *iobuf,
const void **ll_dest, const void **ll_source,
- uint16_t *net_proto );
+ uint16_t *net_proto, unsigned int *flags );
/**
* Initialise link-layer address
*
const void *ll_source );
extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
uint16_t net_proto, const void *ll_dest,
- const void *ll_source );
+ const void *ll_source, unsigned int flags );
extern void net_poll ( void );
/**
const void *iob_ll_dest;
const void *iob_ll_src;
uint16_t iob_net_proto;
+ unsigned int iob_flags;
int rc;
EFI_STATUS efirc;
/* Attempt to decode link-layer header */
if ( ( rc = ll_protocol->pull ( snpdev->netdev, iobuf, &iob_ll_dest,
- &iob_ll_src, &iob_net_proto ) ) != 0 ){
+ &iob_ll_src, &iob_net_proto,
+ &iob_flags ) ) != 0 ) {
DBGC ( snpdev, "SNPDEV %p could not parse header: %s\n",
snpdev, strerror ( rc ) );
efirc = RC_TO_EFIRC ( rc );
const void *ll_source, uint16_t net_proto );
static int net80211_ll_pull ( struct net_device *netdev,
struct io_buffer *iobuf, const void **ll_dest,
- const void **ll_source, uint16_t * net_proto );
+ const void **ll_source, uint16_t * net_proto,
+ unsigned int *flags );
/** @} */
/**
* @ret ll_dest Link-layer destination address
* @ret ll_source Link-layer source
* @ret net_proto Network-layer protocol, in network byte order
+ * @ret flags Packet flags
* @ret rc Return status code
*
* This expects and removes both the 802.11 frame header and the 802.2
static int net80211_ll_pull ( struct net_device *netdev __unused,
struct io_buffer *iobuf,
const void **ll_dest, const void **ll_source,
- uint16_t * net_proto )
+ uint16_t * net_proto, unsigned int *flags )
{
struct ieee80211_frame *hdr = iobuf->data;
struct ieee80211_llc_snap_header *lhdr =
*ll_dest = hdr->addr1;
*ll_source = hdr->addr3;
*net_proto = lhdr->ethertype;
+ *flags = ( ( is_multicast_ether_addr ( hdr->addr1 ) ?
+ LL_MULTICAST : 0 ) |
+ ( is_broadcast_ether_addr ( hdr->addr1 ) ?
+ LL_BROADCAST : 0 ) );
return 0;
}
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
- *
*/
static int aoe_rx ( struct io_buffer *iobuf,
struct net_device *netdev __unused,
const void *ll_dest __unused,
- const void *ll_source ) {
+ const void *ll_source,
+ unsigned int flags __unused ) {
struct aoehdr *aoehdr = iobuf->data;
struct aoe_command *aoecmd;
int rc;
* @v iobuf I/O buffer
* @v netdev Network device
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
*
* This handles ARP requests and responses as detailed in RFC826. The
*/
static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
const void *ll_dest __unused,
- const void *ll_source __unused ) {
+ const void *ll_source __unused,
+ unsigned int flags __unused ) {
struct arphdr *arphdr = iobuf->data;
struct arp_net_protocol *arp_net_protocol;
struct net_protocol *net_protocol;
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
*
* This function takes ownership of the I/O buffer passed to it.
*/
static int eapol_rx ( struct io_buffer *iob, struct net_device *netdev,
- const void *ll_dest, const void *ll_source ) {
+ const void *ll_dest, const void *ll_source,
+ unsigned int flags __unused ) {
struct eapol_frame *eapol = iob->data;
struct eapol_handler *handler;
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
*/
static int eth_slow_rx ( struct io_buffer *iobuf,
struct net_device *netdev,
const void *ll_dest __unused,
- const void *ll_source __unused ) {
+ const void *ll_source __unused,
+ unsigned int flags __unused ) {
union eth_slow_packet *eth_slow = iobuf->data;
/* Sanity checks */
* @ret ll_dest Link-layer destination address
* @ret ll_source Source link-layer address
* @ret net_proto Network-layer protocol, in network-byte order
+ * @ret flags Packet flags
* @ret rc Return status code
*/
static int eth_pull ( struct net_device *netdev __unused,
struct io_buffer *iobuf, const void **ll_dest,
- const void **ll_source, uint16_t *net_proto ) {
+ const void **ll_source, uint16_t *net_proto,
+ unsigned int *flags ) {
struct ethhdr *ethhdr = iobuf->data;
/* Sanity check */
*ll_dest = ethhdr->h_dest;
*ll_source = ethhdr->h_source;
*net_proto = ethhdr->h_protocol;
+ *flags = ( ( is_multicast_ether_addr ( ethhdr->h_dest ) ?
+ LL_MULTICAST : 0 ) |
+ ( is_broadcast_ether_addr ( ethhdr->h_dest ) ?
+ LL_BROADCAST : 0 ) );
return 0;
}
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
*/
static int fcoe_rx ( struct io_buffer *iobuf, struct net_device *netdev,
- const void *ll_dest, const void *ll_source ) {
+ const void *ll_dest, const void *ll_source,
+ unsigned int flags __unused ) {
struct fcoe_header *fcoehdr;
struct fcoe_footer *fcoeftr;
struct fcoe_port *fcoe;
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
*/
static int fcoe_fip_rx ( struct io_buffer *iobuf,
struct net_device *netdev,
const void *ll_dest,
- const void *ll_source __unused ) {
+ const void *ll_source __unused,
+ unsigned int flags __unused ) {
struct fip_header *fiphdr = iobuf->data;
struct fip_descriptors descs;
struct fip_handler *handler;
/**
* Process incoming packets
*
- * @v iobuf I/O buffer
- * @v netdev Network device
- * @v ll_dest Link-layer destination address
- * @v ll_source Link-layer destination source
+ * @v iobuf I/O buffer
+ * @v netdev Network device
+ * @v ll_dest Link-layer destination address
+ * @v ll_source Link-layer destination source
+ * @v flags Packet flags
+ * @ret rc Return status code
*
* This function expects an IP4 network datagram. It processes the headers
* and sends it to the transport layer.
static int ipv4_rx ( struct io_buffer *iobuf,
struct net_device *netdev __unused,
const void *ll_dest __unused,
- const void *ll_source __unused ) {
+ const void *ll_source __unused,
+ unsigned int flags __unused ) {
struct iphdr *iphdr = iobuf->data;
size_t hdrlen;
size_t len;
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
*
* This function processes a IPv6 packet
*/
static int ipv6_rx ( struct io_buffer *iobuf,
__unused struct net_device *netdev,
__unused const void *ll_dest,
- __unused const void *ll_source ) {
+ __unused const void *ll_source,
+ __unused unsigned int flags ) {
struct ip6_header *ip6hdr = iobuf->data;
union {
* @v net_proto Network-layer protocol, in network-byte order
* @v ll_dest Destination link-layer address
* @v ll_source Source link-layer address
+ * @v flags Packet flags
* @ret rc Return status code
*/
int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
- uint16_t net_proto, const void *ll_dest, const void *ll_source ) {
+ uint16_t net_proto, const void *ll_dest, const void *ll_source,
+ unsigned int flags ) {
struct net_protocol *net_protocol;
/* Hand off to network-layer protocol, if any */
for_each_table_entry ( net_protocol, NET_PROTOCOLS ) {
if ( net_protocol->net_proto == net_proto )
return net_protocol->rx ( iobuf, netdev, ll_dest,
- ll_source );
+ ll_source, flags );
}
DBGC ( netdev, "NETDEV %s unknown network protocol %04x\n",
const void *ll_dest;
const void *ll_source;
uint16_t net_proto;
+ unsigned int flags;
int rc;
/* Poll and process each network device */
ll_protocol = netdev->ll_protocol;
if ( ( rc = ll_protocol->pull ( netdev, iobuf,
&ll_dest, &ll_source,
- &net_proto ) ) != 0 ) {
+ &net_proto,
+ &flags ) ) != 0 ) {
free_iob ( iobuf );
continue;
}
/* Hand packet to network layer */
if ( ( rc = net_rx ( iob_disown ( iobuf ), netdev,
net_proto, ll_dest,
- ll_source ) ) != 0 ) {
+ ll_source, flags ) ) != 0 ) {
/* Record error for diagnosis */
netdev_rx_err ( netdev, NULL, rc );
}
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
*
* This is a dummy method which simply discards RARP packets.
static int rarp_rx ( struct io_buffer *iobuf,
struct net_device *netdev __unused,
const void *ll_dest __unused,
- const void *ll_source __unused ) {
+ const void *ll_source __unused,
+ unsigned int flags __unused ) {
free_iob ( iobuf );
return 0;
}
const void *ll_dest;
const void *ll_source;
uint16_t net_proto;
+ unsigned int flags;
int rc;
/* Strip link-layer header and preserve link-layer header fields */
ll_protocol = netdev->ll_protocol;
if ( ( rc = ll_protocol->pull ( netdev, iobuf, &ll_dest, &ll_source,
- &net_proto ) ) != 0 ) {
+ &net_proto, &flags ) ) != 0 ) {
DBGC ( netdev, "VLAN %s could not parse link-layer header: "
"%s\n", netdev->name, strerror ( rc ) );
return rc;
* @v trunk Trunk network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
*/
static int vlan_rx ( struct io_buffer *iobuf, struct net_device *trunk,
- const void *ll_dest, const void *ll_source ) {
+ const void *ll_dest, const void *ll_source,
+ unsigned int flags __unused ) {
struct vlan_header *vlanhdr = iobuf->data;
struct net_device *netdev;
struct ll_protocol *ll_protocol;
* @v netdev Network device
* @v ll_dest Link-layer destination address
* @v ll_source Link-layer source address
+ * @v flags Packet flags
* @ret rc Return status code
*/
static int lotest_rx ( struct io_buffer *iobuf,
struct net_device *netdev __unused,
const void *ll_dest __unused,
- const void *ll_source __unused ) {
+ const void *ll_source __unused,
+ unsigned int flags __unused ) {
free_iob ( iobuf );
return -ENOTSUP;
}
const void *ll_dest;
const void *ll_source;
uint16_t net_proto;
+ unsigned int flags;
unsigned int i;
unsigned int successes;
int rc;
/* Check received packet */
if ( ( rc = receiver->ll_protocol->pull ( receiver, iobuf,
&ll_dest, &ll_source,
- &net_proto ) ) != 0 ){
+ &net_proto,
+ &flags ) ) != 0 ) {
printf ( "\nFailed to strip link-layer header: %s",
strerror ( rc ) );
goto done;