PDP11, VAX, ETHER: Generalize XQ device address filtering
Add optional enabling of broadcast address to hash based filter model. LANCE based devices which use its AUTODIN II based hash generally match the broadcast address independent of the contents of the multicast hash. This change to XQ mostly undoes the prior change to pdp11_xq and brings the functionality into sim_ether so that it is generally available for future ethernet devices.
This commit is contained in:
parent
40d4609385
commit
8b33921c92
4 changed files with 53 additions and 14 deletions
|
@ -742,11 +742,15 @@ t_stat xq_show_filters (FILE* st, UNIT* uptr, int32 val, CONST void* desc)
|
||||||
{
|
{
|
||||||
CTLR* xq = xq_unit2ctlr(uptr);
|
CTLR* xq = xq_unit2ctlr(uptr);
|
||||||
char buffer[20];
|
char buffer[20];
|
||||||
size_t i;
|
int i;
|
||||||
|
|
||||||
if (xq->var->mode == XQ_T_DELQA_PLUS) {
|
if (xq->var->mode == XQ_T_DELQA_PLUS) {
|
||||||
eth_mac_fmt(&xq->var->init.phys, buffer);
|
eth_mac_fmt(&xq->var->init.phys, buffer);
|
||||||
fprintf(st, "Physical Address=%s\n", buffer);
|
fprintf(st, "Physical Address=%s\n", buffer);
|
||||||
|
for (i=1; i<xq->var->etherface->addr_count; i++) {
|
||||||
|
eth_mac_fmt((ETH_MAC*)xq->var->etherface->filter_address[i], buffer);
|
||||||
|
fprintf(st, "Additional Filter:[%2d]: %s\n", (int)i, buffer);
|
||||||
|
}
|
||||||
if (xq->var->etherface->hash_filter) {
|
if (xq->var->etherface->hash_filter) {
|
||||||
fprintf(st, "Multicast Hash: ");
|
fprintf(st, "Multicast Hash: ");
|
||||||
for (i=0; i<sizeof(xq->var->etherface->hash); ++i)
|
for (i=0; i<sizeof(xq->var->etherface->hash); ++i)
|
||||||
|
@ -2403,9 +2407,7 @@ t_stat xq_wr_srqr_action(CTLR* xq)
|
||||||
xq->var->sanity.quarter_secs = 4*xq->var->init.hit_timeout;
|
xq->var->sanity.quarter_secs = 4*xq->var->init.hit_timeout;
|
||||||
}
|
}
|
||||||
xq->var->icr = xq->var->init.options & XQ_IN_OP_INT;
|
xq->var->icr = xq->var->init.options & XQ_IN_OP_INT;
|
||||||
memcpy (&xq->var->turbo_macs[0], &xq->var->init.phys, sizeof (xq->var->turbo_macs[0]));
|
status = eth_filter_hash_ex (xq->var->etherface, 1, &xq->var->init.phys, 0, xq->var->init.mode & XQ_IN_MO_PRO, TRUE, &xq->var->init.hash_filter);
|
||||||
memset (&xq->var->turbo_macs[1], 0xFF, sizeof (xq->var->turbo_macs[1])); /* LANCE explicitly also matches the broadcast address */
|
|
||||||
status = eth_filter_hash (xq->var->etherface, 2, xq->var->turbo_macs, 0, xq->var->init.mode & XQ_IN_MO_PRO, &xq->var->init.hash_filter);
|
|
||||||
xq->dev->dctrl = saved_debug; /* restore original debugging */
|
xq->dev->dctrl = saved_debug; /* restore original debugging */
|
||||||
}
|
}
|
||||||
/* start the read service timer or enable asynch reading as appropriate */
|
/* start the read service timer or enable asynch reading as appropriate */
|
||||||
|
@ -2927,9 +2929,7 @@ t_stat xq_attach(UNIT* uptr, CONST char* cptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xq->var->mode == XQ_T_DELQA_PLUS) {
|
if (xq->var->mode == XQ_T_DELQA_PLUS) {
|
||||||
memcpy (&xq->var->turbo_macs[0], &xq->var->init.phys, sizeof (xq->var->turbo_macs[0]));
|
eth_filter_hash_ex (xq->var->etherface, 1, &xq->var->init.phys, 0, xq->var->init.mode & XQ_IN_MO_PRO, TRUE, &xq->var->init.hash_filter);
|
||||||
memset (&xq->var->turbo_macs[1], 0xFF, sizeof (xq->var->turbo_macs[1])); /* LANCE explicitly also matches the broadcast address */
|
|
||||||
eth_filter_hash (xq->var->etherface, 2, xq->var->turbo_macs, 0, xq->var->init.mode & XQ_IN_MO_PRO, &xq->var->init.hash_filter);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (xq->var->setup.valid) {
|
if (xq->var->setup.valid) {
|
||||||
|
|
|
@ -285,7 +285,6 @@ struct xq_device {
|
||||||
uint16 pending_interrupt; /* Pending Interrupt - DELQA-T only */
|
uint16 pending_interrupt; /* Pending Interrupt - DELQA-T only */
|
||||||
struct xq_turbo_init_block
|
struct xq_turbo_init_block
|
||||||
init;
|
init;
|
||||||
ETH_MAC turbo_macs[2]; /* Hardware MAC address + broadcast */
|
|
||||||
struct transmit_buffer_descriptor
|
struct transmit_buffer_descriptor
|
||||||
xring[XQ_TURBO_XM_BCNT]; /* Transmit Buffer Ring */
|
xring[XQ_TURBO_XM_BCNT]; /* Transmit Buffer Ring */
|
||||||
uint32 tbindx; /* Transmit Buffer Ring Index */
|
uint32 tbindx; /* Transmit Buffer Ring Index */
|
||||||
|
|
42
sim_ether.c
42
sim_ether.c
|
@ -4014,15 +4014,24 @@ return SCPE_OK;
|
||||||
t_stat eth_filter(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
t_stat eth_filter(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
||||||
ETH_BOOL all_multicast, ETH_BOOL promiscuous)
|
ETH_BOOL all_multicast, ETH_BOOL promiscuous)
|
||||||
{
|
{
|
||||||
return eth_filter_hash(dev, addr_count, addresses,
|
return eth_filter_hash_ex(dev, addr_count, addresses,
|
||||||
all_multicast, promiscuous,
|
all_multicast, promiscuous, FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stat eth_filter_hash(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
t_stat eth_filter_hash(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
||||||
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
|
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
|
||||||
ETH_MULTIHASH* const hash)
|
ETH_MULTIHASH* const hash)
|
||||||
{
|
{
|
||||||
|
return eth_filter_hash_ex(dev, addr_count, addresses,
|
||||||
|
all_multicast, promiscuous, TRUE,
|
||||||
|
hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat eth_filter_hash_ex(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses,
|
||||||
|
ETH_BOOL all_multicast, ETH_BOOL promiscuous,
|
||||||
|
ETH_BOOL match_broadcast, ETH_MULTIHASH* const hash)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
char buf[116+66*ETH_FILTER_MAX];
|
char buf[116+66*ETH_FILTER_MAX];
|
||||||
char mac[20];
|
char mac[20];
|
||||||
|
@ -4035,7 +4044,7 @@ struct bpf_program bpf;
|
||||||
if (!dev) return SCPE_UNATT;
|
if (!dev) return SCPE_UNATT;
|
||||||
|
|
||||||
/* filter count OK? */
|
/* filter count OK? */
|
||||||
if ((addr_count < 0) || (addr_count > ETH_FILTER_MAX))
|
if ((addr_count < 0) || ((addr_count + (match_broadcast ? 1 : 0)) > ETH_FILTER_MAX))
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
else
|
else
|
||||||
if (!addresses && (addr_count != 0))
|
if (!addresses && (addr_count != 0))
|
||||||
|
@ -4050,6 +4059,11 @@ if (dev->reflections == -1)
|
||||||
for (i = 0; i < addr_count; i++)
|
for (i = 0; i < addr_count; i++)
|
||||||
memcpy(dev->filter_address[i], addresses[i], sizeof(ETH_MAC));
|
memcpy(dev->filter_address[i], addresses[i], sizeof(ETH_MAC));
|
||||||
dev->addr_count = addr_count;
|
dev->addr_count = addr_count;
|
||||||
|
if (match_broadcast) {
|
||||||
|
memset(&dev->filter_address[addr_count], 0xFF, sizeof(ETH_MAC));
|
||||||
|
++addr_count;
|
||||||
|
}
|
||||||
|
dev->addr_count = addr_count;
|
||||||
|
|
||||||
/* store other flags */
|
/* store other flags */
|
||||||
dev->all_multicast = all_multicast;
|
dev->all_multicast = all_multicast;
|
||||||
|
@ -4219,6 +4233,26 @@ fprintf(st, " Read Queue: High: %d\n", dev->read_queue.high);
|
||||||
fprintf(st, " Read Queue: Loss: %d\n", dev->read_queue.loss);
|
fprintf(st, " Read Queue: Loss: %d\n", dev->read_queue.loss);
|
||||||
fprintf(st, " Peak Write Queue Size: %d\n", dev->write_queue_peak);
|
fprintf(st, " Peak Write Queue Size: %d\n", dev->write_queue_peak);
|
||||||
#endif
|
#endif
|
||||||
|
if (dev->error_needs_reset)
|
||||||
|
fprintf(st, " In Error Needs Reset: True\n");
|
||||||
|
if (dev->error_reopen_count)
|
||||||
|
fprintf(st, " Error Reopen Count: %d\n", (int)dev->error_reopen_count);
|
||||||
|
if (1) {
|
||||||
|
int i, count = 0;
|
||||||
|
ETH_MAC zeros = {0, 0, 0, 0, 0, 0};
|
||||||
|
char buffer[20];
|
||||||
|
|
||||||
|
for (i = 0; i < ETH_FILTER_MAX; i++) {
|
||||||
|
if (memcmp(zeros, &dev->filter_address[i], sizeof(ETH_MAC))) {
|
||||||
|
eth_mac_fmt(&dev->filter_address[i], buffer);
|
||||||
|
fprintf(st, " MAC Filter[%2d]: %s\n", count++, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dev->all_multicast)
|
||||||
|
fprintf(st, " All Multicast mode: Enabled\n");
|
||||||
|
if (dev->promiscuous)
|
||||||
|
fprintf(st, " Promiscuous mode: Enabled\n");
|
||||||
if (dev->bpf_filter)
|
if (dev->bpf_filter)
|
||||||
fprintf(st, " BPF Filter: %s\n", dev->bpf_filter);
|
fprintf(st, " BPF Filter: %s\n", dev->bpf_filter);
|
||||||
#if defined(HAVE_SLIRP_NETWORK)
|
#if defined(HAVE_SLIRP_NETWORK)
|
||||||
|
|
10
sim_ether.h
10
sim_ether.h
|
@ -342,11 +342,17 @@ t_stat eth_filter (ETH_DEV* dev, int addr_count, /* set filter on incomin
|
||||||
ETH_MAC* const addresses,
|
ETH_MAC* const addresses,
|
||||||
ETH_BOOL all_multicast,
|
ETH_BOOL all_multicast,
|
||||||
ETH_BOOL promiscuous);
|
ETH_BOOL promiscuous);
|
||||||
t_stat eth_filter_hash (ETH_DEV* dev, int addr_count, /* set filter on incoming packets with AUTODIN II based hash */
|
t_stat eth_filter_hash (ETH_DEV* dev, int addr_count, /* set filter on incoming packets with hash */
|
||||||
ETH_MAC* const addresses,
|
ETH_MAC* const addresses,
|
||||||
ETH_BOOL all_multicast,
|
ETH_BOOL all_multicast,
|
||||||
ETH_BOOL promiscuous,
|
ETH_BOOL promiscuous,
|
||||||
ETH_MULTIHASH* const hash);
|
ETH_MULTIHASH* const hash); /* AUTODIN II based 8 byte imperfect hash */
|
||||||
|
t_stat eth_filter_hash_ex (ETH_DEV* dev, int addr_count,/* set filter on incoming packets with hash */
|
||||||
|
ETH_MAC* const addresses,
|
||||||
|
ETH_BOOL all_multicast,
|
||||||
|
ETH_BOOL promiscuous,
|
||||||
|
ETH_BOOL match_broadcast,
|
||||||
|
ETH_MULTIHASH* const hash); /* AUTODIN II based 8 byte imperfect hash */
|
||||||
t_stat eth_check_address_conflict (ETH_DEV* dev,
|
t_stat eth_check_address_conflict (ETH_DEV* dev,
|
||||||
ETH_MAC* const address);
|
ETH_MAC* const address);
|
||||||
const char *eth_version (void); /* Version of dynamically loaded library (pcap) */
|
const char *eth_version (void); /* Version of dynamically loaded library (pcap) */
|
||||||
|
|
Loading…
Add table
Reference in a new issue