udp: Allow loopback connections from host using configured unicast address
Likely for testing purposes only: allow connections from host to guest or namespace using, as connection target, the configured, possibly global unicast address. In this case, we have to map the destination address to a link-local address, and for port-based tracked responses, the source address needs to be again the unicast address: not loopback, not link-local. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
89678c5157
commit
9afd87b733
1 changed files with 18 additions and 2 deletions
20
udp.c
20
udp.c
|
@ -125,13 +125,15 @@
|
||||||
* @sock: Socket bound to source port used as index
|
* @sock: Socket bound to source port used as index
|
||||||
* @ts: Activity timestamp from tap, used for socket aging
|
* @ts: Activity timestamp from tap, used for socket aging
|
||||||
* @ts_local: Timestamp of tap packet to gateway address, aging for local bind
|
* @ts_local: Timestamp of tap packet to gateway address, aging for local bind
|
||||||
* @loopback: Whether local bind should use loopback address as source
|
* @loopback: Whether local bind maps to loopback address as source
|
||||||
|
* @gua: Whether local bind maps to configured unicast address as source
|
||||||
*/
|
*/
|
||||||
struct udp_tap_port {
|
struct udp_tap_port {
|
||||||
int sock;
|
int sock;
|
||||||
time_t ts;
|
time_t ts;
|
||||||
time_t ts_local;
|
time_t ts_local;
|
||||||
int loopback;
|
int loopback;
|
||||||
|
int gua;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -701,10 +703,13 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events,
|
||||||
b->ip6h.saddr = b->s_in6.sin6_addr;
|
b->ip6h.saddr = b->s_in6.sin6_addr;
|
||||||
} else if (IN6_IS_ADDR_LOOPBACK(&b->s_in6.sin6_addr) ||
|
} else if (IN6_IS_ADDR_LOOPBACK(&b->s_in6.sin6_addr) ||
|
||||||
!memcmp(&b->s_in6.sin6_addr, &c->addr6_seen,
|
!memcmp(&b->s_in6.sin6_addr, &c->addr6_seen,
|
||||||
|
sizeof(c->addr6)) ||
|
||||||
|
!memcmp(&b->s_in6.sin6_addr, &c->addr6,
|
||||||
sizeof(c->addr6))) {
|
sizeof(c->addr6))) {
|
||||||
in_port_t src = htons(b->s_in6.sin6_port);
|
in_port_t src = htons(b->s_in6.sin6_port);
|
||||||
|
|
||||||
b->ip6h.daddr = c->addr6_ll_seen;
|
b->ip6h.daddr = c->addr6_ll_seen;
|
||||||
|
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&c->gw6))
|
if (IN6_IS_ADDR_LINKLOCAL(&c->gw6))
|
||||||
b->ip6h.saddr = c->gw6;
|
b->ip6h.saddr = c->gw6;
|
||||||
else
|
else
|
||||||
|
@ -717,6 +722,12 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events,
|
||||||
else
|
else
|
||||||
udp_tap_map[V6][src].loopback = 0;
|
udp_tap_map[V6][src].loopback = 0;
|
||||||
|
|
||||||
|
if (!memcmp(&b->s_in6.sin6_addr, &c->addr6,
|
||||||
|
sizeof(c->addr6)))
|
||||||
|
udp_tap_map[V6][src].gua = 1;
|
||||||
|
else
|
||||||
|
udp_tap_map[V6][src].gua = 0;
|
||||||
|
|
||||||
bitmap_set(udp_act[V6][UDP_ACT_TAP], src);
|
bitmap_set(udp_act[V6][UDP_ACT_TAP], src);
|
||||||
} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) &&
|
} else if (!IN6_IS_ADDR_UNSPECIFIED(&c->dns6_fwd) &&
|
||||||
!memcmp(&b->s_in6.sin6_addr, &c->dns6_fwd,
|
!memcmp(&b->s_in6.sin6_addr, &c->dns6_fwd,
|
||||||
|
@ -987,6 +998,8 @@ int udp_tap_handler(struct ctx *c, int af, void *addr,
|
||||||
if (!udp_tap_map[V6][dst].ts_local ||
|
if (!udp_tap_map[V6][dst].ts_local ||
|
||||||
udp_tap_map[V6][dst].loopback)
|
udp_tap_map[V6][dst].loopback)
|
||||||
s_in6.sin6_addr = in6addr_loopback;
|
s_in6.sin6_addr = in6addr_loopback;
|
||||||
|
else if (udp_tap_map[V6][dst].gua)
|
||||||
|
s_in6.sin6_addr = c->addr6;
|
||||||
else
|
else
|
||||||
s_in6.sin6_addr = c->addr6_seen;
|
s_in6.sin6_addr = c->addr6_seen;
|
||||||
} else if (!memcmp(addr, &c->dns6_fwd, sizeof(c->dns6_fwd)) &&
|
} else if (!memcmp(addr, &c->dns6_fwd, sizeof(c->dns6_fwd)) &&
|
||||||
|
@ -1212,8 +1225,11 @@ static void udp_timer_one(struct ctx *c, int v6, enum udp_act_type type,
|
||||||
if (ts->tv_sec - tp->ts > UDP_CONN_TIMEOUT)
|
if (ts->tv_sec - tp->ts > UDP_CONN_TIMEOUT)
|
||||||
s = tp->sock;
|
s = tp->sock;
|
||||||
|
|
||||||
if (ts->tv_sec - tp->ts_local > UDP_CONN_TIMEOUT)
|
if (ts->tv_sec - tp->ts_local > UDP_CONN_TIMEOUT) {
|
||||||
tp->ts_local = 0;
|
tp->ts_local = 0;
|
||||||
|
tp->loopback = 0;
|
||||||
|
tp->gua = 0;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case UDP_ACT_INIT_CONN:
|
case UDP_ACT_INIT_CONN:
|
||||||
|
|
Loading…
Reference in a new issue