int sysnet_interface_set_mtu(VPNInterface *i, unsigned int mtu) { int err; struct nl_cache *link_cache; struct nl_sock *sock; struct rtnl_link *link; struct rtnl_link *new_link; sock = nl_socket_alloc(); nl_connect(sock, NETLINK_ROUTE); rtnl_link_alloc_cache(sock, AF_UNSPEC, &link_cache); link = rtnl_link_get_by_name(link_cache, i->name); new_link = rtnl_link_alloc(); if (!link) { tox_trace(i->context->tox, "can't find link \"%s\"", i->name); return -1; } rtnl_link_set_mtu(new_link, mtu); if ((err = rtnl_link_change(sock, link, new_link, 0)) < 0) { tox_trace(i->context->tox, "unable to change link \"%s\" flags: %s", rtnl_link_get_name(link), nl_geterror(err)); } rtnl_link_put(link); rtnl_link_put(new_link); nl_cache_free(link_cache); nl_socket_free(sock); return 0; }
TError TNlLink::AddVeth(const std::string &name, const std::string &hw, int mtu, int nsFd) { struct rtnl_link *veth, *peer; int ret; peer = rtnl_link_veth_alloc(); if (!peer) return TError(EError::Unknown, "Unable to allocate veth"); rtnl_link_set_name(peer, rtnl_link_get_name(Link)); veth = rtnl_link_veth_get_peer(peer); rtnl_link_set_name(veth, name.c_str()); if (nsFd >= 0) rtnl_link_set_ns_fd(veth, nsFd); if (mtu > 0) { rtnl_link_set_mtu(peer, mtu); rtnl_link_set_mtu(veth, mtu); } if (!hw.empty()) { TNlAddr addr; TError error = addr.Parse(AF_LLC, hw.c_str()); if (error) return error; rtnl_link_set_addr(veth, addr.Addr); } rtnl_link_set_flags(peer, IFF_UP); Dump("add", veth); rtnl_link_put(veth); Dump("add", peer); ret = rtnl_link_add(GetSock(), peer, NLM_F_CREATE | NLM_F_EXCL); if (ret < 0) { rtnl_link_put(peer); return Error(ret, "Cannot add veth"); } rtnl_link_put(peer); return Load(); }
/* * Set the MTU on the specified device. */ int iface_set_interface_mtu(char *ifname, int mtu) { int ret = 0; struct nl_handle *handle = NULL; struct nl_cache *cache = NULL; struct rtnl_link *link = NULL; struct rtnl_link *request = NULL; if (ifname == NULL) { return -1; } if (mtu <= 0) { return -2; } if ((cache = _iface_get_link_cache(&handle)) == NULL) { return -3; } if ((link = rtnl_link_get_by_name(cache, ifname)) == NULL) { ret = -4; goto ifacemtu_error1; } request = rtnl_link_alloc(); rtnl_link_set_mtu(request, mtu); if (rtnl_link_change(handle, link, request, 0)) { ret = -5; goto ifacemtu_error2; } ifacemtu_error2: rtnl_link_put(link); ifacemtu_error1: nl_close(handle); nl_handle_destroy(handle); return ret; }