From 8b33921c923e3db679de0bec0f88142ba75fcd74 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Tue, 14 Dec 2021 11:39:18 -0800 Subject: [PATCH] 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. --- PDP11/pdp11_xq.c | 14 +++++++------- PDP11/pdp11_xq.h | 1 - sim_ether.c | 42 ++++++++++++++++++++++++++++++++++++++---- sim_ether.h | 10 ++++++++-- 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/PDP11/pdp11_xq.c b/PDP11/pdp11_xq.c index fbdaa143..895bade3 100644 --- a/PDP11/pdp11_xq.c +++ b/PDP11/pdp11_xq.c @@ -742,11 +742,15 @@ t_stat xq_show_filters (FILE* st, UNIT* uptr, int32 val, CONST void* desc) { CTLR* xq = xq_unit2ctlr(uptr); char buffer[20]; - size_t i; + int i; if (xq->var->mode == XQ_T_DELQA_PLUS) { eth_mac_fmt(&xq->var->init.phys, buffer); fprintf(st, "Physical Address=%s\n", buffer); + for (i=1; ivar->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) { fprintf(st, "Multicast Hash: "); for (i=0; ivar->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->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])); - 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); + 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); xq->dev->dctrl = saved_debug; /* restore original debugging */ } /* 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) { - memcpy (&xq->var->turbo_macs[0], &xq->var->init.phys, sizeof (xq->var->turbo_macs[0])); - 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); + 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); } else if (xq->var->setup.valid) { diff --git a/PDP11/pdp11_xq.h b/PDP11/pdp11_xq.h index 33d34bea..023dbfe6 100644 --- a/PDP11/pdp11_xq.h +++ b/PDP11/pdp11_xq.h @@ -285,7 +285,6 @@ struct xq_device { uint16 pending_interrupt; /* Pending Interrupt - DELQA-T only */ struct xq_turbo_init_block init; - ETH_MAC turbo_macs[2]; /* Hardware MAC address + broadcast */ struct transmit_buffer_descriptor xring[XQ_TURBO_XM_BCNT]; /* Transmit Buffer Ring */ uint32 tbindx; /* Transmit Buffer Ring Index */ diff --git a/sim_ether.c b/sim_ether.c index bfee3645..95e9489f 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -4014,15 +4014,24 @@ return SCPE_OK; t_stat eth_filter(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses, ETH_BOOL all_multicast, ETH_BOOL promiscuous) { -return eth_filter_hash(dev, addr_count, addresses, - all_multicast, promiscuous, - NULL); +return eth_filter_hash_ex(dev, addr_count, addresses, + all_multicast, promiscuous, FALSE, + NULL); } t_stat eth_filter_hash(ETH_DEV* dev, int addr_count, ETH_MAC* const addresses, ETH_BOOL all_multicast, ETH_BOOL promiscuous, 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; char buf[116+66*ETH_FILTER_MAX]; char mac[20]; @@ -4035,7 +4044,7 @@ struct bpf_program bpf; if (!dev) return SCPE_UNATT; /* 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; else if (!addresses && (addr_count != 0)) @@ -4050,6 +4059,11 @@ if (dev->reflections == -1) for (i = 0; i < addr_count; i++) memcpy(dev->filter_address[i], addresses[i], sizeof(ETH_MAC)); 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 */ 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, " Peak Write Queue Size: %d\n", dev->write_queue_peak); #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) fprintf(st, " BPF Filter: %s\n", dev->bpf_filter); #if defined(HAVE_SLIRP_NETWORK) diff --git a/sim_ether.h b/sim_ether.h index 5b5c9128..d0f30541 100644 --- a/sim_ether.h +++ b/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_BOOL all_multicast, 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_BOOL all_multicast, 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, ETH_MAC* const address); const char *eth_version (void); /* Version of dynamically loaded library (pcap) */