Skip to content

Commit

Permalink
mctpd: Set initial route MTU to interface minimum
Browse files Browse the repository at this point in the history
This allows better compatibility with devices that have a low
initial allowed packet size and require application negotiation
to increase that packet size.

Previously the MTU was left at 0, so matching the currently
set MTU of the interface.

Signed-off-by: Matt Johnston <[email protected]>
  • Loading branch information
mkj committed Aug 31, 2024
1 parent ed7378a commit 7a33524
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 14 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
now associated with the interface object, they no longer take the
interface name as their first argument.

6. In mctpd the initial route MTU for an endpoint is now set to the minimum MTU
of the interface. This allows better compatibility with devices that
have a low initial allowed packet size and require application negotiation
to increase that packet size. Previously the initial MTU was left as the
interface default (normally the maximum MTU).
The .SetMTU method can be used to set the endpoint route MTU.

### Fixed

1. mctpd: EID assignments now work in the case where a new endpoint has a
Expand Down
58 changes: 45 additions & 13 deletions src/mctp-netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ struct linkmap_entry {
int net;
bool up;

uint32_t min_mtu;
uint32_t max_mtu;

mctp_eid_t *local_eids;
size_t num_local;

Expand Down Expand Up @@ -54,7 +57,7 @@ static int fill_linkmap(mctp_nl *nl);
static void sort_linkmap(mctp_nl *nl);
static int linkmap_add_entry(mctp_nl *nl, struct ifinfomsg *info,
const char *ifname, size_t ifname_len, int net,
bool up);
bool up, uint32_t min_mtu, uint32_t max_mtu);
static struct linkmap_entry *entry_byindex(const mctp_nl *nl,
int index);

Expand Down Expand Up @@ -678,10 +681,10 @@ static int parse_getlink_dump(mctp_nl *nl, struct nlmsghdr *nlh, uint32_t len)
struct ifinfomsg *info;

for (; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) {
struct rtattr *rta, *rt_nest, *rt_mctp;
char *ifname;
struct rtattr *rta = NULL, *rt_nest = NULL, *rt_mctp = NULL;
char *ifname = NULL;
size_t ifname_len, rlen, nlen, mlen;
uint32_t net;
uint32_t net, min_mtu = 0, max_mtu = 0;
bool up;

if (nlh->nlmsg_type == NLMSG_DONE)
Expand All @@ -700,7 +703,6 @@ static int parse_getlink_dump(mctp_nl *nl, struct nlmsghdr *nlh, uint32_t len)
rta = (void *)(info + 1);
rlen = NLMSG_PAYLOAD(nlh, sizeof(*info));

rt_mctp = false;
rt_nest = mctp_get_rtnlmsg_attr(IFLA_AF_SPEC, rta, rlen, &nlen);
if (rt_nest) {
rt_mctp = mctp_get_rtnlmsg_attr(AF_MCTP, rt_nest, nlen, &mlen);
Expand All @@ -709,21 +711,33 @@ static int parse_getlink_dump(mctp_nl *nl, struct nlmsghdr *nlh, uint32_t len)
/* Skip non-MCTP interfaces */
continue;
}
if (!mctp_get_rtnlmsg_attr_u32(IFLA_MCTP_NET, rt_mctp, mlen, &net)) {
warnx("Missing IFLA_MCTP_NET");
continue;
}

/* TODO: media type */

ifname = mctp_get_rtnlmsg_attr(IFLA_IFNAME, rta, rlen, &ifname_len);
if (!ifname) {
warnx("no ifname?");
continue;
}

ifname_len = strnlen(ifname, ifname_len);
if (!mctp_get_rtnlmsg_attr_u32(IFLA_MCTP_NET, rt_mctp, mlen, &net)) {
warnx("Missing IFLA_MCTP_NET for %s", ifname);
continue;
}

if (!mctp_get_rtnlmsg_attr_u32(IFLA_MIN_MTU, rta, rlen, &min_mtu)) {
warnx("Missing IFLA_MIN_MTU for %s", ifname);
continue;
}

if (!mctp_get_rtnlmsg_attr_u32(IFLA_MAX_MTU, rta, rlen, &max_mtu)) {
warnx("Missing IFLA_MAX_MTU for %s", ifname);
continue;
}

/* TODO: media type */

up = info->ifi_flags & IFF_UP;
linkmap_add_entry(nl, info, ifname, ifname_len, net, up);
linkmap_add_entry(nl, info, ifname, ifname_len, net, up, min_mtu, max_mtu);
}
// Not done.
return 1;
Expand Down Expand Up @@ -973,6 +987,22 @@ bool mctp_nl_up_byindex(const mctp_nl *nl, int index)
return false;
}

uint32_t mctp_nl_min_mtu_byindex(const mctp_nl *nl, int index)
{
struct linkmap_entry *entry = entry_byindex(nl, index);
if (entry)
return entry->min_mtu;
return 0;
}

uint32_t mctp_nl_max_mtu_byindex(const mctp_nl *nl, int index)
{
struct linkmap_entry *entry = entry_byindex(nl, index);
if (entry)
return entry->max_mtu;
return 0;
}

mctp_eid_t *mctp_nl_addrs_byindex(const mctp_nl *nl, int index,
size_t *ret_num)
{
Expand Down Expand Up @@ -1055,7 +1085,7 @@ int *mctp_nl_if_list(const mctp_nl *nl, size_t *ret_num_ifs)

static int linkmap_add_entry(mctp_nl *nl, struct ifinfomsg *info,
const char *ifname, size_t ifname_len, int net,
bool up)
bool up, uint32_t min_mtu, uint32_t max_mtu)
{
struct linkmap_entry *entry;
size_t newsz;
Expand Down Expand Up @@ -1091,6 +1121,8 @@ static int linkmap_add_entry(mctp_nl *nl, struct ifinfomsg *info,
entry->ifindex = info->ifi_index;
entry->net = net;
entry->up = up;
entry->max_mtu = max_mtu;
entry->min_mtu = min_mtu;
return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions src/mctp-netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ int mctp_nl_ifindex_byname(const mctp_nl *nl, const char *ifname);
const char* mctp_nl_if_byindex(const mctp_nl *nl, int index);
int mctp_nl_net_byindex(const mctp_nl *nl, int index);
bool mctp_nl_up_byindex(const mctp_nl *nl, int index);
/* Returns interface min_mtu, or 0 if bad index */
uint32_t mctp_nl_min_mtu_byindex(const mctp_nl *nl, int index);
/* Returns interface max_mtu, or 0 if bad index */
uint32_t mctp_nl_max_mtu_byindex(const mctp_nl *nl, int index);
/* Caller to free */
mctp_eid_t *mctp_nl_addrs_byindex(const mctp_nl *nl, int index,
size_t *ret_num);
Expand Down
7 changes: 6 additions & 1 deletion src/mctpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ struct peer {
bool have_neigh;
bool have_route;

// set by SetMTU method, 0 otherwise
// MTU for the route. Set to the interface's minimum MTU initially,
// or changed by .SetMTU method
uint32_t mtu;

// malloc()ed list of supported message types, from Get Message Type
Expand Down Expand Up @@ -2161,6 +2162,10 @@ static int setup_added_peer(peer *peer)
{
int rc;

// Set minimum MTU by default for compatibility. Clients can increase
// this with .SetMTU as needed
peer->mtu = mctp_nl_min_mtu_byindex(peer->ctx->nl_query, peer->phys.ifindex);

// add route before querying
add_peer_route(peer);

Expand Down

0 comments on commit 7a33524

Please sign in to comment.