diff options
-rw-r--r-- | arp.c | 34 | ||||
-rw-r--r-- | arp.h | 1 | ||||
-rw-r--r-- | ndp.c | 20 | ||||
-rw-r--r-- | ndp.h | 1 | ||||
-rw-r--r-- | passt.1 | 4 | ||||
-rw-r--r-- | tap.c | 5 |
6 files changed, 63 insertions, 2 deletions
@@ -112,3 +112,37 @@ int arp(const struct ctx *c, struct iov_tail *data) return 1; } + +/** + * arp_send_init_req() - Send initial ARP request to retrieve guest MAC address + * @c: Execution context + */ +void arp_send_init_req(const struct ctx *c) +{ + struct { + struct ethhdr eh; + struct arphdr ah; + struct arpmsg am; + } __attribute__((__packed__)) req; + + /* Ethernet header */ + req.eh.h_proto = htons(ETH_P_ARP); + memcpy(req.eh.h_dest, MAC_BROADCAST, sizeof(req.eh.h_dest)); + memcpy(req.eh.h_source, c->our_tap_mac, sizeof(req.eh.h_source)); + + /* ARP header */ + req.ah.ar_op = htons(ARPOP_REQUEST); + req.ah.ar_hrd = htons(ARPHRD_ETHER); + req.ah.ar_pro = htons(ETH_P_IP); + req.ah.ar_hln = ETH_ALEN; + req.ah.ar_pln = 4; + + /* ARP message */ + memcpy(req.am.sha, c->our_tap_mac, sizeof(req.am.sha)); + memcpy(req.am.sip, &c->ip4.our_tap_addr, sizeof(req.am.sip)); + memcpy(req.am.tha, MAC_BROADCAST, sizeof(req.am.tha)); + memcpy(req.am.tip, &c->ip4.addr, sizeof(req.am.tip)); + + debug("Sending initial ARP request for guest MAC address"); + tap_send_single(c, &req, sizeof(req)); +} @@ -21,5 +21,6 @@ struct arpmsg { } __attribute__((__packed__)); int arp(const struct ctx *c, struct iov_tail *data); +void arp_send_init_req(const struct ctx *c); #endif /* ARP_H */ @@ -438,3 +438,23 @@ void ndp_timer(const struct ctx *c, const struct timespec *now) first: next_ra = now->tv_sec + interval; } + +/** + * ndp_send_init_req() - Send initial NDP NS to retrieve guest MAC address + * @c: Execution context + */ +void ndp_send_init_req(const struct ctx *c) +{ + struct ndp_ns ns = { + .ih = { + .icmp6_type = NS, + .icmp6_code = 0, + .icmp6_router = 0, /* Reserved */ + .icmp6_solicited = 0, /* Reserved */ + .icmp6_override = 0, /* Reserved */ + }, + .target_addr = c->ip6.addr + }; + debug("Sending initial NDP NS request for guest MAC address"); + ndp_send(c, &c->ip6.addr, &ns, sizeof(ns)); +} @@ -11,5 +11,6 @@ struct icmp6hdr; int ndp(const struct ctx *c, const struct in6_addr *saddr, struct iov_tail *data); void ndp_timer(const struct ctx *c, const struct timespec *now); +void ndp_send_init_req(const struct ctx *c); #endif /* NDP_H */ @@ -330,8 +330,8 @@ selected IPv4 default route. .TP .BR \-\-no-ndp -Disable NDP responses. NDP messages coming from guest or target namespace will -be ignored. +Disable Neighbor Discovery. NDP messages coming from guest or target +namespace will be ignored. No initial NDP message will be sent. .TP .BR \-\-no-dhcpv6 @@ -1359,6 +1359,11 @@ static void tap_start_connection(const struct ctx *c) ev.events = EPOLLIN | EPOLLRDHUP; ev.data.u64 = ref.u64; epoll_ctl(c->epollfd, EPOLL_CTL_ADD, c->fd_tap, &ev); + + if (c->ifi4) + arp_send_init_req(c); + if (c->ifi6 && !c->no_ndp) + ndp_send_init_req(c); } /** |