qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2] mark nic as trusted
@ 2009-01-07 16:38 Gleb Natapov
  0 siblings, 0 replies; 2+ messages in thread
From: Gleb Natapov @ 2009-01-07 16:38 UTC (permalink / raw)
  To: qemu-devel

This patch allows to mark specific nic as trusted by adding special
PCI capability. "Trusted" means that it is used for communication
between host and guest and no malicious entity can inject traffic
to the nic.

Signed-off-by: Gleb Natapov <gleb@redhat.com>

diff --git a/hw/e1000.c b/hw/e1000.c
index c326671..cf3ef97 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1045,6 +1045,10 @@ pci_e1000_init(PCIBus *bus, NICInfo *nd, int devfn)
 
     pci_conf[0x3d] = 1; // interrupt pin 0
 
+    if (nd->secure_cookie[0])
+        pci_add_capability(&d->dev, PCI_CAP_ID_SECURE, TRUSTED_CAP_OFFSET,
+                nd->secure_cookie, sizeof(nd->secure_cookie));
+
     d->mmio_index = cpu_register_io_memory(0, e1000_mmio_read,
             e1000_mmio_write, d);
 
diff --git a/hw/eepro100.c b/hw/eepro100.c
index cb3ca09..1fc9cce 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1754,6 +1754,10 @@ static void nic_init(PCIBus * bus, NICInfo * nd,
 
     pci_reset(s);
 
+    if (nd->secure_cookie[0])
+        pci_add_capability(&d->dev, PCI_CAP_ID_SECURE, TRUSTED_CAP_OFFSET,
+                nd->secure_cookie, sizeof(nd->secure_cookie));
+
     /* Add 64 * 2 EEPROM. i82557 and i82558 support a 64 word EEPROM,
      * i82559 and later support 64 or 256 word EEPROM. */
     s->eeprom = eeprom93xx_new(EEPROM_SIZE);
diff --git a/hw/ne2000.c b/hw/ne2000.c
index 3f0ccf5..6a4fd84 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -806,6 +806,11 @@ void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
 
     pci_register_io_region(&d->dev, 0, 0x100,
                            PCI_ADDRESS_SPACE_IO, ne2000_map);
+
+    if (nd->secure_cookie[0])
+        pci_add_capability(&d->dev, PCI_CAP_ID_SECURE, TRUSTED_CAP_OFFSET,
+                nd->secure_cookie, sizeof(nd->secure_cookie));
+
     s = &d->ne2000;
     s->irq = d->dev.irq[0];
     s->pci_dev = (PCIDevice *)d;
diff --git a/hw/pci.c b/hw/pci.c
index 8252d21..05bfa4b 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -536,6 +536,23 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
     bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);
 }
 
+int pci_add_capability(PCIDevice *d, uint8_t cap_id, uint8_t off, uint8_t *buf,
+        int len)
+{
+    uint16_t status = le16_to_cpu(*(uint16_t*)(d->config + 0x06));
+
+    if (off + len + 2 > 0x100 || off < 0x40)
+        return -1;
+
+    d->config[0x06] = cpu_to_le16(status | 0x10);
+    d->config[off] = cap_id;
+    d->config[off + 1] = d->config[0x34];
+    d->config[0x34] = off;
+    memcpy(d->config + off + 2, buf, len);
+
+    return 0;
+}
+
 /***********************************************************/
 /* monitor info on PCI */
 
diff --git a/hw/pci.h b/hw/pci.h
index 3b1caf5..c03db5c 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -74,6 +74,8 @@ typedef struct PCIIORegion {
 
 #define PCI_COMMAND_RESERVED_MASK_HI (PCI_COMMAND_RESERVED >> 8)
 
+#define PCI_CAP_ID_SECURE  0x0f
+
 struct PCIDevice {
     /* PCI config space */
     uint8_t config[256];
@@ -117,6 +119,8 @@ typedef void (*pci_set_irq_fn)(qemu_irq *pic, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
 PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                          qemu_irq *pic, int devfn_min, int nirq);
+int pci_add_capability(PCIDevice *d, uint8_t cap_id, uint8_t off, uint8_t *buf,
+        int len);
 
 void pci_nic_init(PCIBus *bus, NICInfo *nd, int devfn);
 void pci_data_write(void *opaque, uint32_t addr, uint32_t val, int len);
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 30c453c..88aecdb 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -2024,6 +2024,10 @@ void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
     pci_conf[0x3e] = 0x06;
     pci_conf[0x3f] = 0xff;
 
+    if (nd->secure_cookie[0])
+        pci_add_capability(&d->dev, PCI_CAP_ID_SECURE, TRUSTED_CAP_OFFSET,
+                nd->secure_cookie, sizeof(nd->secure_cookie));
+
     /* Handler for memory-mapped I/O */
     d->mmio_index =
       cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index c3ab854..7f31771 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3423,6 +3423,10 @@ void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
     pci_conf[0x3d] = 1;    /* interrupt pin 0 */
     pci_conf[0x34] = 0xdc;
 
+    if (nd->secure_cookie[0])
+        pci_add_capability(&d->dev, PCI_CAP_ID_SECURE, TRUSTED_CAP_OFFSET,
+                nd->secure_cookie, sizeof(nd->secure_cookie));
+
     s = &d->rtl8139;
 
     /* I/O handler for memory-mapped I/O */
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 1f45b2d..7beb4c9 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -309,6 +309,11 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
     if (!n)
         return NULL;
 
+    if (nd->secure_cookie[0])
+        pci_add_capability(&n->vdev.pci_dev, PCI_CAP_ID_SECURE,
+                TRUSTED_CAP_OFFSET, nd->secure_cookie,
+                sizeof(nd->secure_cookie));
+
     n->vdev.get_config = virtio_net_update_config;
     n->vdev.get_features = virtio_net_get_features;
     n->vdev.set_features = virtio_net_set_features;
diff --git a/net.c b/net.c
index 6af4255..4ef78f1 100644
--- a/net.c
+++ b/net.c
@@ -1474,6 +1474,9 @@ int net_client_init(const char *device, const char *p)
         if (get_param_value(buf, sizeof(buf), "model", p)) {
             nd->model = strdup(buf);
         }
+        if (get_param_value(buf, sizeof(buf), "trusted", p)) {
+            strncpy(nd->secure_cookie, buf, sizeof(nd->secure_cookie));
+        }
         nd->vlan = vlan;
         nb_nics++;
         vlan->nb_guest_devs++;
diff --git a/net.h b/net.h
index 31c7a30..2201aed 100644
--- a/net.h
+++ b/net.h
@@ -50,6 +50,7 @@ struct NICInfo {
     uint8_t macaddr[6];
     const char *model;
     VLANState *vlan;
+    uint8_t secure_cookie[14];
 };
 
 extern int nb_nics;
@@ -93,4 +94,6 @@ void net_client_check(void);
 #define SMBD_COMMAND "/usr/sbin/smbd"
 #endif
 
+#define TRUSTED_CAP_OFFSET 0xf0
+
 #endif
--
			Gleb.

^ permalink raw reply related	[flat|nested] 2+ messages in thread
* [Qemu-devel] [PATCH v2] mark nic as trusted
@ 2009-01-18 16:04 Gleb Natapov
  0 siblings, 0 replies; 2+ messages in thread
From: Gleb Natapov @ 2009-01-18 16:04 UTC (permalink / raw)
  To: qemu-devel

This patch pass trusted nic mac to a guest through fw config interface.
"Trusted" means that it is used for communication between host and guest
and no malicious entity can inject traffic to the nic.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 4333ed9..9065413 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -287,7 +287,9 @@ void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
     fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
     fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)nographic);
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
-
+    if (trusted_nic)
+        fw_cfg_add_bytes(s, FW_CFG_TRUSTED_NIC, trusted_nic,
+                strlen(trusted_nic));
     register_savevm("fw_cfg", -1, 1, fw_cfg_save, fw_cfg_load, s);
     qemu_register_reset(fw_cfg_reset, s);
     fw_cfg_reset(s);
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index ef8f378..332356b 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -8,6 +8,7 @@
 #define FW_CFG_NOGRAPHIC        0x04
 #define FW_CFG_NB_CPUS          0x05
 #define FW_CFG_MACHINE_ID       0x06
+#define FW_CFG_TRUSTED_NIC      0x07
 #define FW_CFG_MAX_ENTRY        0x10
 
 #define FW_CFG_WRITE_CHANNEL    0x4000
diff --git a/net.c b/net.c
index 35728dd..901e05b 100644
--- a/net.c
+++ b/net.c
@@ -120,6 +120,7 @@
 #define memalign(align, size) malloc(size)
 #endif
 
+char *trusted_nic;
 static VLANState *first_vlan;
 
 /***********************************************************/
@@ -1596,6 +1597,18 @@ int net_client_init(const char *device, const char *p)
         if (get_param_value(buf, sizeof(buf), "model", p)) {
             nd->model = strdup(buf);
         }
+        if (get_param_value(buf, sizeof(buf), "trusted", p)) {
+            int tlen;
+            buf[64] = '\0';
+            tlen = strlen(buf) + 21;
+            trusted_nic = malloc(tlen);
+            if (!trusted_nic)
+                return -1;
+            snprintf(trusted_nic, tlen,
+                    "%02x:%02x:%02x:%02x:%02x:%02x [%s]",
+                    macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4],
+                    macaddr[5], buf);
+        }
         nd->vlan = vlan;
         nd->name = name;
         name = NULL;
diff --git a/sysemu.h b/sysemu.h
index 56eb9b3..70c210a 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -101,6 +101,7 @@ extern int no_quit;
 extern int semihosting_enabled;
 extern int old_param;
 extern const char *bootp_filename;
+extern char *trusted_nic;
 
 #ifdef USE_KQEMU
 extern int kqemu_allowed;
--
			Gleb.

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2009-01-18 16:06 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-07 16:38 [Qemu-devel] [PATCH v2] mark nic as trusted Gleb Natapov
  -- strict thread matches above, loose matches on Subject: below --
2009-01-18 16:04 Gleb Natapov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).