Re: MTU of outgoing Interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The first hack I tried was using RTNETLINK. However, given the destination address, I was given the Path MTU which might be less than the MTU of the outgoing interface. The code is at

http://www.wand.net.nz/~mjl12/netlink-mtu.c

Hmm, looks sane to me and honestly, so far I've only been interested in the FIB's per route mtu setting and didn't care much about the interface mtu itself.

the reason why I care about the interface's MTU is so that I can conduct path MTU and identify path-MTU limiting points in the network.


What is the suggested way to get the outgoing interface's MTU under Linux?

Does the following work for you or did I completely misunderstand your request?


    ip route flush cache; ip route get ${IP_ADDRESS} \
       dev ${PHYS_INTERFACE} ¦ awk '/mtu/ {print $3}'

it does work, although it feels like a sledgehammer approach. I want to be able to do PMTU discovery many times per second without interfering with other processes on the machine. flushing the cache will disrupt normal communications in other processes, particularly on machines with >1500 byte interface MTUs.


what I ended up doing, I put up at http://www.wand.net.nz/~mjl12/netlink-mtu-oif.c

I collect the inteface's index returned from a RTM_GETROUTE message, and then convert that into the interface's name with if_indextoname and then use the SIOCGIFMTU ioctl. This works regardless of the address family of the destination address [i.e. it works on interfaces with just v6 addresses].

The other approach I tried was to take the interface index and get the MTU from rtnetlink using RTM_GETLINK. I was unable to make the call successfully, though. this is what i did:

  memset(buf, 0, sizeof(buf));
  nlmsg  = (struct nlmsghdr *)buf;
  nlmsg->nlmsg_len   = NLMSG_LENGTH(sizeof(struct ifinfomsg));
  nlmsg->nlmsg_type  = RTM_GETLINK;
  nlmsg->nlmsg_flags = NLM_F_REQUEST;
  nlmsg->nlmsg_seq   = seq++;
  nlmsg->nlmsg_pid   = pid;
  ifinfomsg = NLMSG_DATA(nlmsg);
  ifinfomsg->ifi_family = AF_UNSPEC;
  ifinfomsg->ifi_index  = ifindex;
  ifinfomsg->ifi_change = 0xffffffff; /* RFC3549 reserved future use */

however, I got nlmsg->nlmsg_type == NLMSG_ERROR with that call. I also tried supplying the name of the interface with

  rta = (struct rtattr *)(buf+NLMSG_ALIGN(nlmsg->nlmsg_len));
  len = strlen(ifname);
  rta->rta_type = IFLA_IFNAME;
  rta->rta_len  = len;
  nlmsg->nlmsg_len += RTA_LENGTH(len);
  memcpy(RTA_DATA(rta), ifname, len);

although that didn't work either. I was able to use NLM_F_DUMP and get all interfaces, but specifying the interface of actual interest seems like the correct way to go.

I am getting the MTU of the outgoing interface, which is what I wanted to do, but I'm wondering what I'm doing wrong with RM_GETLINK, and would appreciate any clues.

Finally, I found that kernel 2.4.26 is automatically fragmenting my v6 probes to the path MTU, presumably with the fragmentation header - although I did not confirm that, which means that I was unable to see any MTU changes in the path. I got around this by using

  i = IPV6_PMTUDISC_DONT;
  setsockopt(udp6, SOL_IPV6, IPV6_MTU_DISCOVER, &i, sizeof(i));
  i = IPV6_PMTUDISC_DO;
  setsockopt(udp6, SOL_IPV6, IPV6_MTU_DISCOVER, &i, sizeof(i));

before sending each probe. is there a way to tell the kernel not to fragment your packets regardless of any knowledge it has of the PMTU?

Thanks

Matthew
-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux