Commit 7f97e9cd authored by Alessandro Rubini's avatar Alessandro Rubini

arch-wrs: fixes for vlan

The way vlan frames are received is different on wrs than in normal
Linux. Likely my own driver (for wrs hardware) is not doing the right
thing.

So, when we receive tagged frames, they reach us as-is (not as the
payload only, with "aux" data on a side). This commit considers this
case.

The commit also fixes a pair of other details -- mostly, the amount of
"short packet of 0 bytes, ignored", by returning -2 to mean "drop with
no error".
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>

SQUASH fix for ARCH_WRS
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent d3613623
......@@ -9,6 +9,12 @@
#include "common-fun.h"
#include "../lib/network_types.h"
#ifdef CONFIG_ARCH_WRS
#define ARCH_IS_WRS 1
#else
#define ARCH_IS_WRS 0
#endif
static void *msg_copy_header(MsgHeader *dest, MsgHeader *src)
{
return memcpy(dest, src, sizeof(MsgHeader));
......@@ -38,7 +44,11 @@ void pp_prepare_pointers(struct pp_instance *ppi)
break;
case PPSI_PROTO_VLAN:
ppi->tx_offset = sizeof(struct pp_vlanhdr);
ppi->rx_offset = ETH_HLEN;
/* Hack warning: with wrs we get the whole header */
if (ARCH_IS_WRS)
ppi->rx_offset = sizeof(struct pp_vlanhdr);
else
ppi->rx_offset = ETH_HLEN;
break;
case PPSI_PROTO_UDP:
ppi->tx_offset = 0;
......
......@@ -161,6 +161,7 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
TimeInternal *t)
{
struct ethhdr *hdr = pkt;
struct pp_vlanhdr *vhdr = pkt;
struct wrs_socket *s;
struct msghdr msg;
struct iovec entry;
......@@ -239,19 +240,40 @@ static int wrs_recv_msg(struct pp_instance *ppi, int fd, void *pkt, int len,
}
drop:
/* aux is only there if we asked for it, thus PROTO_VLAN */
if (aux) {
printf("aux: %x proto %x\n", aux->tp_vlan_tci,
ntohs(hdr->h_proto));
if (0) {
fprintf(stderr,
"PPSi error: unexpected auxiliary data\n");
errno = EINVAL;
return -1;
}
}
/*
* While on PC-class ethernet driver we see the internal frame,
* our simple WR driver returns the whole frame. No aux pointer
* is there, at this point in time. So unroll vlan header.
*/
if (vhdr->h_tpid == htons(0x8100)) {
int vlan = ntohs(vhdr->h_tci) & 0xfff;
/* With PROTO_VLAN, we bound to ETH_P_ALL: we got all frames */
if (hdr->h_proto != htons(ETH_P_1588))
return 0;
if (vhdr->h_proto != htons(ETH_P_1588))
return -2; /* like "dropped", so no error message */
/* Also, we got the vlan, and we can discard it if not ours */
for (i = 0; i < ppi->nvlans; i++)
if (ppi->vlans[i] == aux->tp_vlan_tci)
if (ppi->vlans[i] == vlan)
break; /* ok */
if (i == ppi->nvlans)
return 0; /* not ours */
return -2; /* not ours: say it's dropped */
ppi->peer_vid = ppi->vlans[i];
} else {
if (hdr->h_proto != htons(ETH_P_1588))
return -2; /* again: drop unrelated frames */
ppi->peer_vid = 0;
}
......@@ -278,9 +300,6 @@ int wrs_net_recv(struct pp_instance *ppi, void *pkt, int len,
ret = wrs_recv_msg(ppi, ch2->fd, pkt, len, t);
if (ret <= 0)
return ret;
if (hdr->h_proto != htons(ETH_P_1588))
return 0;
memcpy(ppi->peer, hdr->h_source, ETH_ALEN);
if (pp_diag_allow(ppi, frames, 2)) {
if (ppi->proto == PPSI_PROTO_VLAN)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment