Permalink
Browse files

Improved MTU setting, fixed issue caused by linux preventing MTU bein…

…g set below 1280.
  • Loading branch information...
Caleb James DeLisle
Caleb James DeLisle committed Aug 10, 2012
1 parent cb806ed commit e43dd73b7e5d0967f860bc6d79eaeabe58f09080
Showing with 58 additions and 20 deletions.
  1. +10 −3 cjdroute.c
  2. +8 −5 interface/TUNConfigurator.h
  3. +40 −12 interface/TUNConfigurator_Linux.c
View
@@ -67,16 +67,22 @@
#define WORST_CASE_OVERHEAD ( \
/* TODO: Headers_IPv4_SIZE */ 20 \
+ Headers_UDPHeader_SIZE \
- + /* Nonce */ 4 \
- + /* Poly1306 authenticator */ 16 \
+ + 4 /* Nonce */ \
+ + 16 /* Poly1305 authenticator */ \
+ Headers_SwitchHeader_SIZE \
+ Headers_CryptoAuth_SIZE \
+ Headers_IP6Header_SIZE \
+ Headers_CryptoAuth_SIZE \
)
/** The default MTU, assuming the external MTU is 1492 (common for PPPoE DSL) */
-#define DEFAULT_MTU (1492 - WORST_CASE_OVERHEAD)
+#define DEFAULT_MTU ( \
+ 1492 \
+ - WORST_CASE_OVERHEAD \
+ + Headers_IP6Header_SIZE /* The OS subtracts the IP6 header. */ \
+ + Headers_CryptoAuth_SIZE /* Linux won't let set the MTU below 1280.
+ TODO: make sure we never hand off to a node for which the CA session is expired. */ \
+)
struct User
{
@@ -535,6 +541,7 @@ int main(int argc, char** argv)
logger,
AbortHandler_INSTANCE);
struct Jmp jmp;
+
Jmp_try(jmp) {
TUNConfigurator_setIpAddress(
assignedTunName, myAddr.ip6.bytes, 8, logger, &jmp.handler);
@@ -29,7 +29,10 @@
* The error code for any function which fails to get a socket for configuring an interface.
* Multiple functions may return this error.
*/
-#define TUNConfigurator_ERROR_GETTING_ADMIN_SOCKET -2
+#define TUNConfigurator_ERROR_GETTING_ADMIN_SOCKET 1
+
+/** If there is an error bringing the interface up. */
+#define TUNConfigurator_ERROR_ENABLING_INTERFACE 2
/**
* Open the TUN device.
@@ -62,10 +65,10 @@ void* TUNConfigurator_initTun(const char* interfaceName,
* @param logger
* @param eh if this function fails, it will raise one of the following.
* TUNConfigurator_setIpAddress_INTERNAL Catch all exception code for failures.
- * TUNConfigurator_setIpAddress_ADMIN_SOCKET Error getting admin socket for interface.
+ * TUNConfigurator_ERROR_GETTING_ADMIN_SOCKET Error getting admin socket for interface.
+ * TUNConfigurator_ERROR_ENABLING_INTERFACE If the interface cannot be brought up.
*/
#define TUNConfigurator_setIpAddress_INTERNAL -1
-#define TUNConfigurator_setIpAddress_ADMIN_SOCKET TUNConfigurator_ERROR_GETTING_ADMIN_SOCKET
void TUNConfigurator_setIpAddress(const char* interfaceName,
const uint8_t address[16],
int prefixLen,
@@ -80,10 +83,10 @@ void TUNConfigurator_setIpAddress(const char* interfaceName,
* @param logger where to write information.
* @param eh if this function fails, it will raise one of the following.
* TUNConfigurator_setMTU_INTERNAL Catch all exception code for failures.
- * TUNConfigurator_setMTU_ADMIN_SOCKET Error getting admin socket for interface.
+ * TUNConfigurator_ERROR_GETTING_ADMIN_SOCKET Error getting admin socket for interface.
+ * TUNConfigurator_ERROR_ENABLING_INTERFACE If the interface cannot be brought up.
*/
#define TUNConfigurator_setMTU_INTERNAL -1
-#define TUNConfigurator_setMTU_ADMIN_SOCKET TUNConfigurator_ERROR_GETTING_ADMIN_SOCKET
void TUNConfigurator_setMTU(const char* interfaceName,
uint32_t mtu,
struct Log* logger,
@@ -113,6 +113,7 @@ static int socketForIfName(const char* interfaceName,
"socket() failed: [%s]", strerror(errno));
}
+ memset(ifRequestOut, 0, sizeof(struct ifreq));
strncpy(ifRequestOut->ifr_name, interfaceName, IFNAMSIZ);
if (ioctl(s, SIOCGIFINDEX, ifRequestOut) < 0) {
@@ -124,29 +125,56 @@ static int socketForIfName(const char* interfaceName,
return s;
}
+static void checkInterfaceUp(int socket,
+ struct ifreq* ifRequest,
+ struct Log* logger,
+ struct Except* eh)
+{
+ if (ioctl(socket, SIOCGIFFLAGS, ifRequest) < 0) {
+ int err = errno;
+ close(socket);
+ Except_raise(eh, TUNConfigurator_ERROR_ENABLING_INTERFACE,
+ "ioctl(SIOCGIFFLAGS) failed: [%s]", strerror(err));
+ }
+
+ if (ifRequest->ifr_flags & IFF_UP & IFF_RUNNING) {
+ // already up.
+ return;
+ }
+
+ Log_info(logger, "Bringing up interface [%s]", ifRequest->ifr_name);
+
+ ifRequest->ifr_flags |= IFF_UP | IFF_RUNNING;
+ if (ioctl(socket, SIOCSIFFLAGS, ifRequest) < 0) {
+ int err = errno;
+ close(socket);
+ Except_raise(eh, TUNConfigurator_ERROR_ENABLING_INTERFACE,
+ "ioctl(SIOCSIFFLAGS) failed: [%s]", strerror(err));
+ }
+}
+
void TUNConfigurator_setIpAddress(const char* interfaceName,
const uint8_t address[16],
int prefixLen,
struct Log* logger,
struct Except* eh)
{
struct ifreq ifRequest;
- struct in6_ifreq ifr6;
int s = socketForIfName(interfaceName, eh, &ifRequest);
+ struct in6_ifreq ifr6;
+ memset(&ifr6, 0, sizeof(struct in6_ifreq));
+ // checkInterfaceUp() clobbers the ifindex.
ifr6.ifr6_ifindex = ifRequest.ifr_ifindex;
- ifr6.ifr6_prefixlen = prefixLen;
+
+ checkInterfaceUp(s, &ifRequest, logger, eh);
+
uint8_t myIp[40];
AddrTools_printIp(myIp, address);
- inet_pton(AF_INET6, (char*) myIp, &ifr6.ifr6_addr);
+ Log_info(logger, "Setting IPv6 address [%s] for device [%s]", myIp, interfaceName);
- ifRequest.ifr_flags |= IFF_UP | IFF_RUNNING;
- if (ioctl(s, SIOCSIFFLAGS, &ifRequest) < 0) {
- int err = errno;
- close(s);
- Except_raise(eh, TUNConfigurator_setIpAddress_INTERNAL,
- "ioctl(SIOCSIFFLAGS) failed: [%s]", strerror(err));
- }
+ ifr6.ifr6_prefixlen = prefixLen;
+ inet_pton(AF_INET6, (char*) myIp, &ifr6.ifr6_addr);
if (ioctl(s, SIOCSIFADDR, &ifr6) < 0) {
int err = errno;
@@ -161,11 +189,11 @@ void TUNConfigurator_setMTU(const char* interfaceName,
struct Log* logger,
struct Except* eh)
{
- Log_info(logger, "Setting MTU for device [%s] to [%u] bytes.", interfaceName, mtu);
-
struct ifreq ifRequest;
int s = socketForIfName(interfaceName, eh, &ifRequest);
+ Log_info(logger, "Setting MTU for device [%s] to [%u] bytes.", interfaceName, mtu);
+
ifRequest.ifr_mtu = mtu;
if (ioctl(s, SIOCSIFMTU, &ifRequest) < 0) {
int err = errno;

0 comments on commit e43dd73

Please sign in to comment.