Support jumbo frames, by allocating enough memory for the device MTU.
authorBen Pfaff <blp@nicira.com>
Fri, 28 Mar 2008 21:01:54 +0000 (14:01 -0700)
committerBen Pfaff <blp@nicira.com>
Tue, 1 Apr 2008 16:52:59 +0000 (09:52 -0700)
switch/TODO
switch/datapath.c
switch/netdev.c
switch/netdev.h

index 502694c5bfc2c8bf95091183beeefef1bba2eb17..c4377330e16c749d165bf8a6f3278cd5c8a46606 100644 (file)
@@ -1,7 +1,5 @@
 * Give it a more specific name (ofswitch? ofp-switch?)
 
-* Jumbo frames (drop ETH_TOTAL_MAX?).
-
 * Test memory leaks.
 
 * Test packet header modifications.
index 264c9af9c68e252aa43d6b71a4bba72919ab0911..e1b0916f7f096ee99a5c8e62c85d781b934b879a 100644 (file)
@@ -158,7 +158,9 @@ dp_run(struct datapath *dp)
              * to the controller or adding a vlan tag, plus an extra 2 bytes to
              * allow IP headers to be aligned on a 4-byte boundary.  */
             const int headroom = 128 + 2;
-            buffer = buffer_new(ETH_TOTAL_MAX + headroom);
+            const int hard_header = VLAN_ETH_HEADER_LEN;
+            const int mtu = netdev_get_mtu(p->netdev);
+            buffer = buffer_new(headroom + hard_header + mtu);
             buffer->data += headroom;
         }
         error = netdev_recv(p->netdev, buffer, false);
index 3c280222165959afc4565354c9aa47f23229dd4c..915db35742451739cf4350f312983e65470ba784 100644 (file)
@@ -68,6 +68,7 @@ struct netdev {
     int fd;
     uint8_t etheraddr[ETH_ADDR_LEN];
     int speed;
+    int mtu;
     uint32_t features;
     int save_flags;
 };
@@ -212,6 +213,7 @@ netdev_open(const char *name, struct netdev **netdev_)
     socklen_t rcvbuf_len;
     size_t rcvbuf;
     uint8_t etheraddr[ETH_ADDR_LEN];
+    int mtu;
     int error;
     struct netdev *netdev;
 
@@ -259,7 +261,7 @@ netdev_open(const char *name, struct netdev **netdev_)
         rcvbuf -= n_bytes;
     }
 
-    /* Get ethernet device index and hardware address. */
+    /* Get ethernet device index. */
     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
     if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
         VLOG_ERR("ioctl(SIOCGIFINDEX) on %s device failed: %s",
@@ -267,6 +269,8 @@ netdev_open(const char *name, struct netdev **netdev_)
         goto error;
     }
     ifindex = ifr.ifr_ifindex;
+
+    /* Get MAC address. */
     if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
         VLOG_ERR("ioctl(SIOCGIFHWADDR) on %s device failed: %s",
                  name, strerror(errno));
@@ -279,11 +283,20 @@ netdev_open(const char *name, struct netdev **netdev_)
     }
     memcpy(etheraddr, ifr.ifr_hwaddr.sa_data, sizeof etheraddr);
 
+    /* Get MTU. */
+    if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) {
+        VLOG_ERR("ioctl(SIOCGIFMTU) on %s device failed: %s",
+                 name, strerror(errno));
+        goto error;
+    }
+    mtu = ifr.ifr_mtu;
+
     /* Allocate network device. */
     netdev = xmalloc(sizeof *netdev);
     netdev->name = xstrdup(name);
     netdev->fd = fd;
     memcpy(netdev->etheraddr, etheraddr, sizeof etheraddr);
+    netdev->mtu = mtu;
 
     /* Get speed, features. */
     do_ethtool(netdev);
@@ -442,6 +455,12 @@ netdev_get_name(const struct netdev *netdev)
     return netdev->name;
 }
 
+int
+netdev_get_mtu(const struct netdev *netdev) 
+{
+    return netdev->mtu;
+}
+
 int
 netdev_get_speed(const struct netdev *netdev) 
 {
index 8d997925c1f85bfa089c28f98000779ebe7301e3..e15ceb6805ad8db646ca7a7a5446384c586c4cbb 100644 (file)
@@ -47,6 +47,7 @@ int netdev_send(struct netdev *, struct buffer *, bool block);
 const uint8_t *netdev_get_etheraddr(const struct netdev *);
 int netdev_get_fd(const struct netdev *);
 const char *netdev_get_name(const struct netdev *);
+int netdev_get_mtu(const struct netdev *);
 int netdev_get_speed(const struct netdev *);
 uint32_t netdev_get_features(const struct netdev *);