tcp, udp: Don't pre-fill IPv4 destination address in headers
Because packets sent on the tap interface will always be going to the guest/namespace, we more-or-less know what address they'll be going to. So we pre-fill this destination address in our header buffers for IPv4. We can't do the same for IPv6 because we could need either the global or link-local address for the guest. In future we're going to want more flexibility for the destination address, so this pre-filling will get in the way. Change the flow so we always fill in the IPv4 destination address for each packet, rather than prefilling it from proto_update_l2_buf(). In fact for TCP we already redundantly filled the destination for each packet anyway. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
5bf200ae8a
commit
955dd3251c
8 changed files with 15 additions and 32 deletions
10
passt.c
10
passt.c
|
@ -117,13 +117,11 @@ static void timer_init(struct ctx *c, const struct timespec *now)
|
||||||
* proto_update_l2_buf() - Update scatter-gather L2 buffers in protocol handlers
|
* proto_update_l2_buf() - Update scatter-gather L2 buffers in protocol handlers
|
||||||
* @eth_d: Ethernet destination address, NULL if unchanged
|
* @eth_d: Ethernet destination address, NULL if unchanged
|
||||||
* @eth_s: Ethernet source address, NULL if unchanged
|
* @eth_s: Ethernet source address, NULL if unchanged
|
||||||
* @ip_da: Pointer to IPv4 destination address, NULL if unchanged
|
|
||||||
*/
|
*/
|
||||||
void proto_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
void proto_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s)
|
||||||
const struct in_addr *ip_da)
|
|
||||||
{
|
{
|
||||||
tcp_update_l2_buf(eth_d, eth_s, ip_da);
|
tcp_update_l2_buf(eth_d, eth_s);
|
||||||
udp_update_l2_buf(eth_d, eth_s, ip_da);
|
udp_update_l2_buf(eth_d, eth_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -247,7 +245,7 @@ int main(int argc, char **argv)
|
||||||
if (!c.no_icmp)
|
if (!c.no_icmp)
|
||||||
icmp_init();
|
icmp_init();
|
||||||
|
|
||||||
proto_update_l2_buf(c.mac_guest, c.mac, &c.ip4.addr);
|
proto_update_l2_buf(c.mac_guest, c.mac);
|
||||||
|
|
||||||
if (c.ifi4 && !c.no_dhcp)
|
if (c.ifi4 && !c.no_dhcp)
|
||||||
dhcp_init();
|
dhcp_init();
|
||||||
|
|
4
passt.h
4
passt.h
|
@ -303,7 +303,7 @@ struct ctx {
|
||||||
int low_rmem;
|
int low_rmem;
|
||||||
};
|
};
|
||||||
|
|
||||||
void proto_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
void proto_update_l2_buf(const unsigned char *eth_d,
|
||||||
const struct in_addr *ip_da);
|
const unsigned char *eth_s);
|
||||||
|
|
||||||
#endif /* PASST_H */
|
#endif /* PASST_H */
|
||||||
|
|
2
pasta.c
2
pasta.c
|
@ -353,7 +353,7 @@ void pasta_ns_conf(struct ctx *c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_update_l2_buf(c->mac_guest, NULL, NULL);
|
proto_update_l2_buf(c->mac_guest, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
8
tap.c
8
tap.c
|
@ -625,10 +625,8 @@ resume:
|
||||||
|
|
||||||
l4_len = l3_len - hlen;
|
l4_len = l3_len - hlen;
|
||||||
|
|
||||||
if (iph->saddr && c->ip4.addr_seen.s_addr != iph->saddr) {
|
if (iph->saddr && c->ip4.addr_seen.s_addr != iph->saddr)
|
||||||
c->ip4.addr_seen.s_addr = iph->saddr;
|
c->ip4.addr_seen.s_addr = iph->saddr;
|
||||||
proto_update_l2_buf(NULL, NULL, &c->ip4.addr_seen);
|
|
||||||
}
|
|
||||||
|
|
||||||
l4h = packet_get(in, i, sizeof(*eh) + hlen, l4_len, NULL);
|
l4h = packet_get(in, i, sizeof(*eh) + hlen, l4_len, NULL);
|
||||||
if (!l4h)
|
if (!l4h)
|
||||||
|
@ -969,7 +967,7 @@ redo:
|
||||||
|
|
||||||
if (memcmp(c->mac_guest, eh->h_source, ETH_ALEN)) {
|
if (memcmp(c->mac_guest, eh->h_source, ETH_ALEN)) {
|
||||||
memcpy(c->mac_guest, eh->h_source, ETH_ALEN);
|
memcpy(c->mac_guest, eh->h_source, ETH_ALEN);
|
||||||
proto_update_l2_buf(c->mac_guest, NULL, NULL);
|
proto_update_l2_buf(c->mac_guest, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ntohs(eh->h_proto)) {
|
switch (ntohs(eh->h_proto)) {
|
||||||
|
@ -1030,7 +1028,7 @@ restart:
|
||||||
|
|
||||||
if (memcmp(c->mac_guest, eh->h_source, ETH_ALEN)) {
|
if (memcmp(c->mac_guest, eh->h_source, ETH_ALEN)) {
|
||||||
memcpy(c->mac_guest, eh->h_source, ETH_ALEN);
|
memcpy(c->mac_guest, eh->h_source, ETH_ALEN);
|
||||||
proto_update_l2_buf(c->mac_guest, NULL, NULL);
|
proto_update_l2_buf(c->mac_guest, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (ntohs(eh->h_proto)) {
|
switch (ntohs(eh->h_proto)) {
|
||||||
|
|
8
tcp.c
8
tcp.c
|
@ -997,10 +997,8 @@ static void tcp_update_check_tcp6(struct tcp6_l2_buf_t *buf)
|
||||||
* tcp_update_l2_buf() - Update L2 buffers with Ethernet and IPv4 addresses
|
* tcp_update_l2_buf() - Update L2 buffers with Ethernet and IPv4 addresses
|
||||||
* @eth_d: Ethernet destination address, NULL if unchanged
|
* @eth_d: Ethernet destination address, NULL if unchanged
|
||||||
* @eth_s: Ethernet source address, NULL if unchanged
|
* @eth_s: Ethernet source address, NULL if unchanged
|
||||||
* @ip_da: Pointer to IPv4 destination address, NULL if unchanged
|
|
||||||
*/
|
*/
|
||||||
void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s)
|
||||||
const struct in_addr *ip_da)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -1014,10 +1012,6 @@ void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
||||||
tap_update_mac(&b6->taph, eth_d, eth_s);
|
tap_update_mac(&b6->taph, eth_d, eth_s);
|
||||||
tap_update_mac(&b4f->taph, eth_d, eth_s);
|
tap_update_mac(&b4f->taph, eth_d, eth_s);
|
||||||
tap_update_mac(&b6f->taph, eth_d, eth_s);
|
tap_update_mac(&b6f->taph, eth_d, eth_s);
|
||||||
|
|
||||||
if (ip_da) {
|
|
||||||
b4f->iph.daddr = b4->iph.daddr = ip_da->s_addr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
tcp.h
3
tcp.h
|
@ -26,8 +26,7 @@ void tcp_timer(struct ctx *c, const struct timespec *ts);
|
||||||
void tcp_defer_handler(struct ctx *c);
|
void tcp_defer_handler(struct ctx *c);
|
||||||
|
|
||||||
void tcp_sock_set_bufsize(const struct ctx *c, int s);
|
void tcp_sock_set_bufsize(const struct ctx *c, int s);
|
||||||
void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
void tcp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s);
|
||||||
const struct in_addr *ip_da);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* union tcp_epoll_ref - epoll reference portion for TCP connections
|
* union tcp_epoll_ref - epoll reference portion for TCP connections
|
||||||
|
|
9
udp.c
9
udp.c
|
@ -276,10 +276,8 @@ static void udp_update_check4(struct udp4_l2_buf_t *buf)
|
||||||
* udp_update_l2_buf() - Update L2 buffers with Ethernet and IPv4 addresses
|
* udp_update_l2_buf() - Update L2 buffers with Ethernet and IPv4 addresses
|
||||||
* @eth_d: Ethernet destination address, NULL if unchanged
|
* @eth_d: Ethernet destination address, NULL if unchanged
|
||||||
* @eth_s: Ethernet source address, NULL if unchanged
|
* @eth_s: Ethernet source address, NULL if unchanged
|
||||||
* @ip_da: Pointer to IPv4 destination address, NULL if unchanged
|
|
||||||
*/
|
*/
|
||||||
void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s)
|
||||||
const struct in_addr *ip_da)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -289,10 +287,6 @@ void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
||||||
|
|
||||||
tap_update_mac(&b4->taph, eth_d, eth_s);
|
tap_update_mac(&b4->taph, eth_d, eth_s);
|
||||||
tap_update_mac(&b6->taph, eth_d, eth_s);
|
tap_update_mac(&b6->taph, eth_d, eth_s);
|
||||||
|
|
||||||
if (ip_da) {
|
|
||||||
b4->iph.daddr = ip_da->s_addr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -578,6 +572,7 @@ static size_t udp_update_hdr4(const struct ctx *c, int n, in_port_t dstport,
|
||||||
ip_len = udp4_l2_mh_sock[n].msg_len + sizeof(b->iph) + sizeof(b->uh);
|
ip_len = udp4_l2_mh_sock[n].msg_len + sizeof(b->iph) + sizeof(b->uh);
|
||||||
|
|
||||||
b->iph.tot_len = htons(ip_len);
|
b->iph.tot_len = htons(ip_len);
|
||||||
|
b->iph.daddr = c->ip4.addr_seen.s_addr;
|
||||||
|
|
||||||
src_port = ntohs(b->s_in.sin_port);
|
src_port = ntohs(b->s_in.sin_port);
|
||||||
|
|
||||||
|
|
3
udp.h
3
udp.h
|
@ -16,8 +16,7 @@ int udp_sock_init(const struct ctx *c, int ns, sa_family_t af,
|
||||||
const void *addr, const char *ifname, in_port_t port);
|
const void *addr, const char *ifname, in_port_t port);
|
||||||
int udp_init(struct ctx *c);
|
int udp_init(struct ctx *c);
|
||||||
void udp_timer(struct ctx *c, const struct timespec *ts);
|
void udp_timer(struct ctx *c, const struct timespec *ts);
|
||||||
void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s,
|
void udp_update_l2_buf(const unsigned char *eth_d, const unsigned char *eth_s);
|
||||||
const struct in_addr *ip_da);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* union udp_epoll_ref - epoll reference portion for TCP connections
|
* union udp_epoll_ref - epoll reference portion for TCP connections
|
||||||
|
|
Loading…
Reference in a new issue