Skip to content
Snippets Groups Projects
Commit 097de16e authored by Libor Peltan's avatar Libor Peltan Committed by Daniel Salzman
Browse files

XDP-TCP: announce correct MSS

parent 7142d815
No related branches found
No related tags found
1 merge request!1300Basic implementation of TCP over XDP for Knot server
......@@ -77,6 +77,9 @@ struct knot_xdp_socket {
/*! The kernel has to be woken up by a syscall indication. */
bool kernel_needs_wakeup;
/*! The limit of frame size. */
unsigned frame_limit;
};
/*!
......
......@@ -45,12 +45,15 @@ inline static void msg_init(knot_xdp_msg_t *msg, knot_xdp_msg_flag_t flags)
if (flags & KNOT_XDP_MSG_TCP) {
msg->ackno = 0;
msg->seqno = dnssec_random_uint32_t();
if (flags & KNOT_XDP_MSG_SYN) {
msg->flags |= KNOT_XDP_MSG_MSS;
}
}
}
inline static void msg_init_reply(knot_xdp_msg_t *msg, const knot_xdp_msg_t *query)
{
msg_init_base(msg, query->flags & (KNOT_XDP_MSG_IPV6 | KNOT_XDP_MSG_TCP));
msg_init_base(msg, query->flags & (KNOT_XDP_MSG_IPV6 | KNOT_XDP_MSG_TCP | KNOT_XDP_MSG_MSS));
memcpy(msg->eth_from, query->eth_to, ETH_ALEN);
memcpy(msg->eth_to, query->eth_from, ETH_ALEN);
......
......@@ -262,7 +262,8 @@ inline static void prot_write_udp(void *data, const knot_xdp_msg_t *msg, void *d
}
inline static void prot_write_tcp(void *data, const knot_xdp_msg_t *msg, void *data_end,
uint16_t src_port, uint16_t dst_port, uint32_t chksum)
uint16_t src_port, uint16_t dst_port, uint32_t chksum,
uint16_t mss)
{
struct tcphdr *tcp = data;
......@@ -285,7 +286,7 @@ inline static void prot_write_tcp(void *data, const knot_xdp_msg_t *msg, void *d
hdr_end += PROT_TCP_OPT_LEN_WSC;
*hdr_end++ = PROT_TCP_OPT_NOOP;
if (msg->flags & KNOT_XDP_MSG_MSS) {
uint16_t mss = htobe16(1460); // TODO: set proper MSS value
mss = htobe16(mss);
hdr_end[0] = PROT_TCP_OPT_MSS;
hdr_end[1] = PROT_TCP_OPT_LEN_MSS;
memcpy(&hdr_end[2], &mss, sizeof(mss));
......@@ -322,7 +323,8 @@ inline static uint16_t ipv4_checksum(const uint16_t *ipv4_hdr)
return ~from32to16(sum32);
}
inline static void prot_write_ipv4(void *data, const knot_xdp_msg_t *msg, void *data_end)
inline static void prot_write_ipv4(void *data, const knot_xdp_msg_t *msg,
void *data_end, uint16_t tcp_mss)
{
struct iphdr *ip4 = data;
......@@ -349,13 +351,14 @@ inline static void prot_write_ipv4(void *data, const knot_xdp_msg_t *msg, void *
checksum(&chk, &src->sin_addr, sizeof(src->sin_addr));
checksum(&chk, &dst->sin_addr, sizeof(dst->sin_addr));
prot_write_tcp(data, msg, data_end, src->sin_port, dst->sin_port, chk);
prot_write_tcp(data, msg, data_end, src->sin_port, dst->sin_port, chk, tcp_mss);
} else {
prot_write_udp(data, msg, data_end, src->sin_port, dst->sin_port, 0); // IPv4/UDP requires no checksum
}
}
inline static void prot_write_ipv6(void *data, const knot_xdp_msg_t *msg, void *data_end)
inline static void prot_write_ipv6(void *data, const knot_xdp_msg_t *msg,
void *data_end, uint16_t tcp_mss)
{
struct ipv6hdr *ip6 = data;
......@@ -379,13 +382,14 @@ inline static void prot_write_ipv6(void *data, const knot_xdp_msg_t *msg, void *
checksum(&chk, &dst->sin6_addr, sizeof(dst->sin6_addr));
if (msg->flags & KNOT_XDP_MSG_TCP) {
prot_write_tcp(data, msg, data_end, src->sin6_port, dst->sin6_port, chk);
prot_write_tcp(data, msg, data_end, src->sin6_port, dst->sin6_port, chk, tcp_mss);
} else {
prot_write_udp(data, msg, data_end, src->sin6_port, dst->sin6_port, chk);
}
}
inline static void prot_write_eth(void *data, const knot_xdp_msg_t *msg, void *data_end)
inline static void prot_write_eth(void *data, const knot_xdp_msg_t *msg,
void *data_end, uint16_t tcp_mss)
{
struct ethhdr *eth = data;
......@@ -396,9 +400,9 @@ inline static void prot_write_eth(void *data, const knot_xdp_msg_t *msg, void *d
if (msg->flags & KNOT_XDP_MSG_IPV6) {
eth->h_proto = __constant_htons(ETH_P_IPV6);
prot_write_ipv6(data, msg, data_end);
prot_write_ipv6(data, msg, data_end, tcp_mss);
} else {
eth->h_proto = __constant_htons(ETH_P_IP);
prot_write_ipv4(data, msg, data_end);
prot_write_ipv4(data, msg, data_end, tcp_mss);
}
}
......@@ -29,6 +29,7 @@
#include "libknot/endian.h"
#include "libknot/errcode.h"
#include "libknot/xdp/bpf-user.h"
#include "libknot/xdp/eth.h"
#include "libknot/xdp/msg_init.h"
#include "libknot/xdp/protocols.h"
#include "libknot/xdp/xdp.h"
......@@ -179,6 +180,12 @@ int knot_xdp_init(knot_xdp_socket_t **socket, const char *if_name, int if_queue,
return ret;
}
(*socket)->frame_limit = FRAME_SIZE;
ret = knot_eth_mtu(if_name);
if (ret > 0) {
(*socket)->frame_limit = MIN((unsigned)ret, (*socket)->frame_limit);
}
ret = kxsk_socket_start(iface, listen_port, (*socket)->xsk);
if (ret != KNOT_EOK) {
xsk_socket__delete((*socket)->xsk);
......@@ -339,7 +346,8 @@ int knot_xdp_send(knot_xdp_socket_t *socket, const knot_xdp_msg_t msgs[],
size_t hdr_len = prot_write_hdrs_len(msg);
size_t tot_len = hdr_len + msg->payload.iov_len;
uint8_t *msg_beg = msg->payload.iov_base - hdr_len;
prot_write_eth(msg_beg, msg, msg_beg + tot_len);
prot_write_eth(msg_beg, msg, msg_beg + tot_len,
socket->frame_limit - hdr_len);
*xsk_ring_prod__tx_desc(&socket->tx, idx++) = (struct xdp_desc) {
.addr = msg_beg - socket->umem->frames->bytes,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment