mirror of
https://passt.top/passt
synced 2025-05-23 01:35:35 +02:00
udp: support traceroute in direction tap-socket
Now that ICMP pass-through from socket-to-tap is in place, it is easy to support UDP based traceroute functionality in direction tap-to-socket. We fix that in this commit. Link: https://bugs.passt.top/show_bug.cgi?id=64 Signed-off-by: Jon Maloy <jmaloy@redhat.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
06784d7fc6
commit
a7775e9550
5 changed files with 40 additions and 7 deletions
17
tap.c
17
tap.c
|
@ -559,6 +559,7 @@ PACKET_POOL_DECL(pool_l4, UIO_MAXIOV, pkt_buf);
|
|||
* struct l4_seq4_t - Message sequence for one protocol handler call, IPv4
|
||||
* @msgs: Count of messages in sequence
|
||||
* @protocol: Protocol number
|
||||
* @ttl: Time to live
|
||||
* @source: Source port
|
||||
* @dest: Destination port
|
||||
* @saddr: Source address
|
||||
|
@ -567,6 +568,7 @@ PACKET_POOL_DECL(pool_l4, UIO_MAXIOV, pkt_buf);
|
|||
*/
|
||||
static struct tap4_l4_t {
|
||||
uint8_t protocol;
|
||||
uint8_t ttl;
|
||||
|
||||
uint16_t source;
|
||||
uint16_t dest;
|
||||
|
@ -586,6 +588,7 @@ static struct tap4_l4_t {
|
|||
* @dest: Destination port
|
||||
* @saddr: Source address
|
||||
* @daddr: Destination address
|
||||
* @hop_limit: Hop limit
|
||||
* @msg: Array of messages that can be handled in a single call
|
||||
*/
|
||||
static struct tap6_l4_t {
|
||||
|
@ -598,6 +601,8 @@ static struct tap6_l4_t {
|
|||
struct in6_addr saddr;
|
||||
struct in6_addr daddr;
|
||||
|
||||
uint8_t hop_limit;
|
||||
|
||||
struct pool_l4_t p;
|
||||
} tap6_l4[TAP_SEQS /* Arbitrary: TAP_MSGS in theory, so limit in users */];
|
||||
|
||||
|
@ -786,7 +791,8 @@ resume:
|
|||
#define L4_MATCH(iph, uh, seq) \
|
||||
((seq)->protocol == (iph)->protocol && \
|
||||
(seq)->source == (uh)->source && (seq)->dest == (uh)->dest && \
|
||||
(seq)->saddr.s_addr == (iph)->saddr && (seq)->daddr.s_addr == (iph)->daddr)
|
||||
(seq)->saddr.s_addr == (iph)->saddr && \
|
||||
(seq)->daddr.s_addr == (iph)->daddr && (seq)->ttl == (iph)->ttl)
|
||||
|
||||
#define L4_SET(iph, uh, seq) \
|
||||
do { \
|
||||
|
@ -795,6 +801,7 @@ resume:
|
|||
(seq)->dest = (uh)->dest; \
|
||||
(seq)->saddr.s_addr = (iph)->saddr; \
|
||||
(seq)->daddr.s_addr = (iph)->daddr; \
|
||||
(seq)->ttl = (iph)->ttl; \
|
||||
} while (0)
|
||||
|
||||
if (seq && L4_MATCH(iph, uh, seq) && seq->p.count < UIO_MAXIOV)
|
||||
|
@ -843,7 +850,7 @@ append:
|
|||
for (k = 0; k < p->count; )
|
||||
k += udp_tap_handler(c, PIF_TAP, AF_INET,
|
||||
&seq->saddr, &seq->daddr,
|
||||
p, k, now);
|
||||
seq->ttl, p, k, now);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -966,7 +973,8 @@ resume:
|
|||
(seq)->dest == (uh)->dest && \
|
||||
(seq)->flow_lbl == ip6_get_flow_lbl(ip6h) && \
|
||||
IN6_ARE_ADDR_EQUAL(&(seq)->saddr, saddr) && \
|
||||
IN6_ARE_ADDR_EQUAL(&(seq)->daddr, daddr))
|
||||
IN6_ARE_ADDR_EQUAL(&(seq)->daddr, daddr) && \
|
||||
(seq)->hop_limit == (ip6h)->hop_limit)
|
||||
|
||||
#define L4_SET(ip6h, proto, uh, seq) \
|
||||
do { \
|
||||
|
@ -976,6 +984,7 @@ resume:
|
|||
(seq)->flow_lbl = ip6_get_flow_lbl(ip6h); \
|
||||
(seq)->saddr = *saddr; \
|
||||
(seq)->daddr = *daddr; \
|
||||
(seq)->hop_limit = (ip6h)->hop_limit; \
|
||||
} while (0)
|
||||
|
||||
if (seq && L4_MATCH(ip6h, proto, uh, seq) &&
|
||||
|
@ -1026,7 +1035,7 @@ append:
|
|||
for (k = 0; k < p->count; )
|
||||
k += udp_tap_handler(c, PIF_TAP, AF_INET6,
|
||||
&seq->saddr, &seq->daddr,
|
||||
p, k, now);
|
||||
seq->hop_limit, p, k, now);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
22
udp.c
22
udp.c
|
@ -844,6 +844,7 @@ fail:
|
|||
* @af: Address family, AF_INET or AF_INET6
|
||||
* @saddr: Source address
|
||||
* @daddr: Destination address
|
||||
* @ttl: TTL or hop limit for packets to be sent in this call
|
||||
* @p: Pool of UDP packets, with UDP headers
|
||||
* @idx: Index of first packet to process
|
||||
* @now: Current timestamp
|
||||
|
@ -854,7 +855,8 @@ fail:
|
|||
*/
|
||||
int udp_tap_handler(const struct ctx *c, uint8_t pif,
|
||||
sa_family_t af, const void *saddr, const void *daddr,
|
||||
const struct pool *p, int idx, const struct timespec *now)
|
||||
uint8_t ttl, const struct pool *p, int idx,
|
||||
const struct timespec *now)
|
||||
{
|
||||
const struct flowside *toside;
|
||||
struct mmsghdr mm[UIO_MAXIOV];
|
||||
|
@ -933,6 +935,24 @@ int udp_tap_handler(const struct ctx *c, uint8_t pif,
|
|||
mm[i].msg_hdr.msg_controllen = 0;
|
||||
mm[i].msg_hdr.msg_flags = 0;
|
||||
|
||||
if (ttl != uflow->ttl[tosidx.sidei]) {
|
||||
uflow->ttl[tosidx.sidei] = ttl;
|
||||
if (af == AF_INET) {
|
||||
if (setsockopt(s, IPPROTO_IP, IP_TTL,
|
||||
&ttl, sizeof(ttl)) < 0)
|
||||
flow_perror(uflow,
|
||||
"setsockopt IP_TTL");
|
||||
} else {
|
||||
/* IPv6 hop_limit cannot be only 1 byte */
|
||||
int hop_limit = ttl;
|
||||
|
||||
if (setsockopt(s, SOL_IPV6, IPV6_UNICAST_HOPS,
|
||||
&hop_limit, sizeof(hop_limit)) < 0)
|
||||
flow_perror(uflow,
|
||||
"setsockopt IPV6_UNICAST_HOPS");
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
|
|
3
udp.h
3
udp.h
|
@ -15,7 +15,8 @@ void udp_reply_sock_handler(const struct ctx *c, union epoll_ref ref,
|
|||
uint32_t events, const struct timespec *now);
|
||||
int udp_tap_handler(const struct ctx *c, uint8_t pif,
|
||||
sa_family_t af, const void *saddr, const void *daddr,
|
||||
const struct pool *p, int idx, const struct timespec *now);
|
||||
uint8_t ttl, const struct pool *p, int idx,
|
||||
const struct timespec *now);
|
||||
int udp_sock_init(const struct ctx *c, int ns, const union inany_addr *addr,
|
||||
const char *ifname, in_port_t port);
|
||||
int udp_init(struct ctx *c);
|
||||
|
|
|
@ -137,6 +137,7 @@ static flow_sidx_t udp_flow_new(const struct ctx *c, union flow *flow,
|
|||
uflow = FLOW_SET_TYPE(flow, FLOW_UDP, udp);
|
||||
uflow->ts = now->tv_sec;
|
||||
uflow->s[INISIDE] = uflow->s[TGTSIDE] = -1;
|
||||
uflow->ttl[INISIDE] = uflow->ttl[TGTSIDE] = 0;
|
||||
|
||||
if (s_ini >= 0) {
|
||||
/* When using auto port-scanning the listening port could go
|
||||
|
|
|
@ -8,11 +8,12 @@
|
|||
#define UDP_FLOW_H
|
||||
|
||||
/**
|
||||
* struct udp - Descriptor for a flow of UDP packets
|
||||
* struct udp_flow - Descriptor for a flow of UDP packets
|
||||
* @f: Generic flow information
|
||||
* @closed: Flow is already closed
|
||||
* @ts: Activity timestamp
|
||||
* @s: Socket fd (or -1) for each side of the flow
|
||||
* @ttl: TTL or hop_limit for both sides
|
||||
*/
|
||||
struct udp_flow {
|
||||
/* Must be first element */
|
||||
|
@ -21,6 +22,7 @@ struct udp_flow {
|
|||
bool closed :1;
|
||||
time_t ts;
|
||||
int s[SIDES];
|
||||
uint8_t ttl[SIDES];
|
||||
};
|
||||
|
||||
struct udp_flow *udp_at_sidx(flow_sidx_t sidx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue