From 62a5944bb3aaba58d52327c785991e4154b72fb1 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 28 Mar 2008 14:01:54 -0700 Subject: [PATCH] Support jumbo frames, by allocating enough memory for the device MTU. --- switch/TODO | 2 -- switch/datapath.c | 4 +++- switch/netdev.c | 21 ++++++++++++++++++++- switch/netdev.h | 1 + 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/switch/TODO b/switch/TODO index 502694c5..c4377330 100644 --- a/switch/TODO +++ b/switch/TODO @@ -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. diff --git a/switch/datapath.c b/switch/datapath.c index 264c9af9..e1b0916f 100644 --- a/switch/datapath.c +++ b/switch/datapath.c @@ -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); diff --git a/switch/netdev.c b/switch/netdev.c index 3c280222..915db357 100644 --- a/switch/netdev.c +++ b/switch/netdev.c @@ -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) { diff --git a/switch/netdev.h b/switch/netdev.h index 8d997925..e15ceb68 100644 --- a/switch/netdev.h +++ b/switch/netdev.h @@ -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 *); -- 2.30.2