diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index e0c6804f4..abfd9dea8 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -235,7 +235,8 @@ net_pcap_rx_handler(uint8_t *user, const struct pcap_pkthdr *h, const uint8_t *b net_pcap_t *pcap = (net_pcap_t *) user; memcpy(pcap->pkt.data, bytes, h->caplen); pcap->pkt.len = h->caplen; - network_rx_put_pkt(pcap->card, &pcap->pkt); + if (!(net_cards_conf[pcap->card->card_num].link_state & NET_LINK_DOWN)) + network_rx_put_pkt(pcap->card, &pcap->pkt); } /* Send a packet to the Pcap interface. */ @@ -282,12 +283,14 @@ net_pcap_thread(void *priv) case NET_EVENT_TX: net_event_clear(&pcap->tx_event); - int packets = network_tx_popv(pcap->card, pcap->pktv, PCAP_PKT_BATCH); - for (int i = 0; i < packets; i++) { - h.caplen = pcap->pktv[i].len; - f_pcap_sendqueue_queue(pcap->pcap_queue, &h, pcap->pktv[i].data); + if (!(net_cards_conf[pcap->card->card_num].link_state & NET_LINK_DOWN)) { + int packets = network_tx_popv(pcap->card, pcap->pktv, PCAP_PKT_BATCH); + for (int i = 0; i < packets; i++) { + h.caplen = pcap->pktv[i].len; + f_pcap_sendqueue_queue(pcap->pcap_queue, &h, pcap->pktv[i].data); + } + f_pcap_sendqueue_transmit(pcap->pcap, pcap->pcap_queue, 0); } - f_pcap_sendqueue_transmit(pcap->pcap, pcap->pcap_queue, 0); pcap->pcap_queue->len = 0; break; @@ -333,8 +336,10 @@ net_pcap_thread(void *priv) net_event_clear(&pcap->tx_event); int packets = network_tx_popv(pcap->card, pcap->pktv, PCAP_PKT_BATCH); - for (int i = 0; i < packets; i++) { - net_pcap_in(pcap->pcap, pcap->pktv[i].data, pcap->pktv[i].len); + if (!(net_cards_conf[pcap->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) { + net_pcap_in(pcap->pcap, pcap->pktv[i].data, pcap->pktv[i].len); + } } } diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 4f61a55a8..c7243baac 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -193,11 +193,14 @@ net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque) memcpy(slirp->pkt.data, (uint8_t *) qp, pkt_len); slirp->pkt.len = pkt_len; - if (slirp->during_tx) { - network_rx_on_tx_put_pkt(slirp->card, &slirp->pkt); - slirp->recv_on_tx = 1; - } else - network_rx_put_pkt(slirp->card, &slirp->pkt); + + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + if (slirp->during_tx) { + network_rx_on_tx_put_pkt(slirp->card, &slirp->pkt); + slirp->recv_on_tx = 1; + } else + network_rx_put_pkt(slirp->card, &slirp->pkt); + } return pkt_len; } @@ -362,8 +365,10 @@ net_slirp_rx_deferred_packets(net_slirp_t *slirp) if (slirp->recv_on_tx) { do { packets = network_rx_on_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH); - for (int i = 0; i < packets; i++) - network_rx_put_pkt(slirp->card, &(slirp->pkt_tx_v[i])); + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + network_rx_put_pkt(slirp->card, &(slirp->pkt_tx_v[i])); + } } while (packets > 0); slirp->recv_on_tx = 0; } @@ -403,8 +408,10 @@ net_slirp_thread(void *priv) { slirp->during_tx = 1; int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH); - for (int i = 0; i < packets; i++) - net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + } slirp->during_tx = 0; net_slirp_rx_deferred_packets(slirp); @@ -456,8 +463,10 @@ net_slirp_thread(void *priv) slirp->during_tx = 1; int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH); - for (int i = 0; i < packets; i++) - net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + } slirp->during_tx = 0; net_slirp_rx_deferred_packets(slirp); diff --git a/src/network/net_switch.c b/src/network/net_switch.c index 5fc3a2091..d29513f74 100644 --- a/src/network/net_switch.c +++ b/src/network/net_switch.c @@ -372,25 +372,29 @@ net_switch_thread(void *priv) net_event_clear(&netswitch->tx_event); netswitch->during_tx = 1; packets = network_tx_popv(netswitch->card, netswitch->pkt_tx_v, SWITCH_PKT_BATCH); - for (int i = 0; i < packets; i++) { + if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) { #define MAC_FORMAT "(%02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X)" #define MAC_FORMAT_ARGS(p) (p)[6], (p)[7], (p)[8], (p)[9], (p)[10], (p)[11], (p)[0], (p)[1], (p)[2], (p)[3], (p)[4], (p)[5] - netswitch_log("Network Switch: sending %d-byte packet " MAC_FORMAT "\n", - netswitch->pkt_tx_v[i].len, MAC_FORMAT_ARGS(netswitch->pkt_tx_v[i].data)); + netswitch_log("Network Switch: sending %d-byte packet " MAC_FORMAT "\n", + netswitch->pkt_tx_v[i].len, MAC_FORMAT_ARGS(netswitch->pkt_tx_v[i].data)); - /* Send through all known host interfaces. */ - for (net_switch_hostaddr_t *hostaddr = netswitch->hostaddrs; hostaddr; hostaddr = hostaddr->next) - sendto(hostaddr->socket_tx, - (char *) netswitch->pkt_tx_v[i].data, netswitch->pkt_tx_v[i].len, 0, - &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); + /* Send through all known host interfaces. */ + for (net_switch_hostaddr_t *hostaddr = netswitch->hostaddrs; hostaddr; hostaddr = hostaddr->next) + sendto(hostaddr->socket_tx, + (char *) netswitch->pkt_tx_v[i].data, netswitch->pkt_tx_v[i].len, 0, + &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); + } } netswitch->during_tx = 0; if (netswitch->recv_on_tx) { do { packets = network_rx_on_tx_popv(netswitch->card, netswitch->pkt_tx_v, SWITCH_PKT_BATCH); - for (int i = 0; i < packets; i++) - network_rx_put_pkt(netswitch->card, &(netswitch->pkt_tx_v[i])); + if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + network_rx_put_pkt(netswitch->card, &(netswitch->pkt_tx_v[i])); + } } while (packets > 0); netswitch->recv_on_tx = 0; } @@ -407,9 +411,9 @@ net_switch_thread(void *priv) netswitch_log("Network Switch: recv error (%d)\n", len); } else if ((AS_U64(netswitch->pkt.data[6]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64) { /* A packet we've sent has looped back, drop it. */ - } else if (netswitch->promisc || /* promiscuous mode? */ + } else if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN) && (netswitch->promisc || /* promiscuous mode? */ (netswitch->pkt.data[0] & 1) || /* broadcast packet? */ - ((AS_U64(netswitch->pkt.data[0]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64)) { /* packet for me? */ + ((AS_U64(netswitch->pkt.data[0]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64))) { /* packet for me? */ netswitch_log("Network Switch: receiving %d-byte packet " MAC_FORMAT "\n", len, MAC_FORMAT_ARGS(netswitch->pkt.data)); netswitch->pkt.len = len; diff --git a/src/network/net_vde.c b/src/network/net_vde.c index 4f8d5c21f..6e82d4669 100644 --- a/src/network/net_vde.c +++ b/src/network/net_vde.c @@ -151,10 +151,12 @@ static void net_vde_thread(void *priv) { if (pfd[NET_EVENT_TX].revents & POLLIN) { net_event_clear(&vde->tx_event); int packets = network_tx_popv(vde->card, vde->pktv, VDE_PKT_BATCH); - for (int i=0; ivdeconn, vde->pktv[i].data,vde->pktv[i].len, 0 ); - if (nc == 0) { - vde_log("VDE: Problem, no bytes sent.\n"); + if (!(net_cards_conf[vde->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i=0; ivdeconn, vde->pktv[i].data,vde->pktv[i].len, 0 ); + if (nc == 0) { + vde_log("VDE: Problem, no bytes sent.\n"); + } } } } @@ -163,7 +165,8 @@ static void net_vde_thread(void *priv) { if (pfd[NET_EVENT_RX].revents & POLLIN) { int nc = f_vde_recv(vde->vdeconn, vde->pkt.data, NET_MAX_FRAME, 0); vde->pkt.len = nc; - network_rx_put_pkt(vde->card, &vde->pkt); + if (!(net_cards_conf[vde->card->card_num].link_state & NET_LINK_DOWN)) + network_rx_put_pkt(vde->card, &vde->pkt); } // We have been told to close