passt: Relicense to GPL 2.0, or any later version
In practical terms, passt doesn't benefit from the additional
protection offered by the AGPL over the GPL, because it's not
suitable to be executed over a computer network.
Further, restricting the distribution under the version 3 of the GPL
wouldn't provide any practical advantage either, as long as the passt
codebase is concerned, and might cause unnecessary compatibility
dilemmas.
Change licensing terms to the GNU General Public License Version 2,
or any later version, with written permission from all current and
past contributors, namely: myself, David Gibson, Laine Stump, Andrea
Bolognani, Paul Holzinger, Richard W.M. Jones, Chris Kuhn, Florian
Weimer, Giuseppe Scrivano, Stefan Hajnoczi, and Vasiliy Ulyanov.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2023-04-05 18:11:44 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/* PASST - Plug A Simple Socket Transport
|
passt: Add PASTA mode, major rework
PASTA (Pack A Subtle Tap Abstraction) provides quasi-native host
connectivity to an otherwise disconnected, unprivileged network
and user namespace, similarly to slirp4netns. Given that the
implementation is largely overlapping with PASST, no separate binary
is built: 'pasta' (and 'passt4netns' for clarity) both link to
'passt', and the mode of operation is selected depending on how the
binary is invoked. Usage example:
$ unshare -rUn
# echo $$
1871759
$ ./pasta 1871759 # From another terminal
# udhcpc -i pasta0 2>/dev/null
# ping -c1 pasta.pizza
PING pasta.pizza (64.190.62.111) 56(84) bytes of data.
64 bytes from 64.190.62.111 (64.190.62.111): icmp_seq=1 ttl=255 time=34.6 ms
--- pasta.pizza ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 34.575/34.575/34.575/0.000 ms
# ping -c1 spaghetti.pizza
PING spaghetti.pizza(2606:4700:3034::6815:147a (2606:4700:3034::6815:147a)) 56 data bytes
64 bytes from 2606:4700:3034::6815:147a (2606:4700:3034::6815:147a): icmp_seq=1 ttl=255 time=29.0 ms
--- spaghetti.pizza ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 28.967/28.967/28.967/0.000 ms
This entails a major rework, especially with regard to the storage of
tracked connections and to the semantics of epoll(7) references.
Indexing TCP and UDP bindings merely by socket proved to be
inflexible and unsuitable to handle different connection flows: pasta
also provides Layer-2 to Layer-2 socket mapping between init and a
separate namespace for local connections, using a pair of splice()
system calls for TCP, and a recvmmsg()/sendmmsg() pair for UDP local
bindings. For instance, building on the previous example:
# ip link set dev lo up
# iperf3 -s
$ iperf3 -c ::1 -Z -w 32M -l 1024k -P2 | tail -n4
[SUM] 0.00-10.00 sec 52.3 GBytes 44.9 Gbits/sec 283 sender
[SUM] 0.00-10.43 sec 52.3 GBytes 43.1 Gbits/sec receiver
iperf Done.
epoll(7) references now include a generic part in order to
demultiplex data to the relevant protocol handler, using 24
bits for the socket number, and an opaque portion reserved for
usage by the single protocol handlers, in order to track sockets
back to corresponding connections and bindings.
A number of fixes pertaining to TCP state machine and congestion
window handling are also included here.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-07-17 06:34:53 +00:00
|
|
|
* for qemu/UNIX domain socket mode
|
|
|
|
*
|
|
|
|
* PASTA - Pack A Subtle Tap Abstraction
|
|
|
|
* for network namespace/tap device mode
|
2021-04-13 19:59:47 +00:00
|
|
|
*
|
|
|
|
* dhcpv6.c - Minimalistic DHCPv6 server for PASST
|
|
|
|
*
|
|
|
|
* Copyright (c) 2021 Red Hat GmbH
|
|
|
|
* Author: Stefano Brivio <sbrivio@redhat.com>
|
|
|
|
*/
|
|
|
|
|
2021-10-21 02:26:08 +00:00
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <net/if_arp.h>
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#include <netinet/udp.h>
|
|
|
|
#include <netinet/if_ether.h>
|
2021-04-13 19:59:47 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <time.h>
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
#include <limits.h>
|
2021-10-21 02:26:08 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
#include "packet.h"
|
passt: Add PASTA mode, major rework
PASTA (Pack A Subtle Tap Abstraction) provides quasi-native host
connectivity to an otherwise disconnected, unprivileged network
and user namespace, similarly to slirp4netns. Given that the
implementation is largely overlapping with PASST, no separate binary
is built: 'pasta' (and 'passt4netns' for clarity) both link to
'passt', and the mode of operation is selected depending on how the
binary is invoked. Usage example:
$ unshare -rUn
# echo $$
1871759
$ ./pasta 1871759 # From another terminal
# udhcpc -i pasta0 2>/dev/null
# ping -c1 pasta.pizza
PING pasta.pizza (64.190.62.111) 56(84) bytes of data.
64 bytes from 64.190.62.111 (64.190.62.111): icmp_seq=1 ttl=255 time=34.6 ms
--- pasta.pizza ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 34.575/34.575/34.575/0.000 ms
# ping -c1 spaghetti.pizza
PING spaghetti.pizza(2606:4700:3034::6815:147a (2606:4700:3034::6815:147a)) 56 data bytes
64 bytes from 2606:4700:3034::6815:147a (2606:4700:3034::6815:147a): icmp_seq=1 ttl=255 time=29.0 ms
--- spaghetti.pizza ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 28.967/28.967/28.967/0.000 ms
This entails a major rework, especially with regard to the storage of
tracked connections and to the semantics of epoll(7) references.
Indexing TCP and UDP bindings merely by socket proved to be
inflexible and unsuitable to handle different connection flows: pasta
also provides Layer-2 to Layer-2 socket mapping between init and a
separate namespace for local connections, using a pair of splice()
system calls for TCP, and a recvmmsg()/sendmmsg() pair for UDP local
bindings. For instance, building on the previous example:
# ip link set dev lo up
# iperf3 -s
$ iperf3 -c ::1 -Z -w 32M -l 1024k -P2 | tail -n4
[SUM] 0.00-10.00 sec 52.3 GBytes 44.9 Gbits/sec 283 sender
[SUM] 0.00-10.43 sec 52.3 GBytes 43.1 Gbits/sec receiver
iperf Done.
epoll(7) references now include a generic part in order to
demultiplex data to the relevant protocol handler, using 24
bits for the socket number, and an opaque portion reserved for
usage by the single protocol handlers, in order to track sockets
back to corresponding connections and bindings.
A number of fixes pertaining to TCP state machine and congestion
window handling are also included here.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-07-17 06:34:53 +00:00
|
|
|
#include "util.h"
|
2021-04-13 19:59:47 +00:00
|
|
|
#include "passt.h"
|
|
|
|
#include "tap.h"
|
2022-09-24 07:53:15 +00:00
|
|
|
#include "log.h"
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_hdr - DHCPv6 option header
|
|
|
|
* @t: Option type
|
|
|
|
* @l: Option length, network order
|
|
|
|
*/
|
|
|
|
struct opt_hdr {
|
|
|
|
uint16_t t;
|
2023-01-06 00:43:12 +00:00
|
|
|
# define OPT_CLIENTID htons_constant(1)
|
|
|
|
# define OPT_SERVERID htons_constant(2)
|
|
|
|
# define OPT_IA_NA htons_constant(3)
|
|
|
|
# define OPT_IA_TA htons_constant(4)
|
|
|
|
# define OPT_IAAADR htons_constant(5)
|
|
|
|
# define OPT_STATUS_CODE htons_constant(13)
|
|
|
|
# define STATUS_NOTONLINK htons_constant(4)
|
|
|
|
# define OPT_DNS_SERVERS htons_constant(23)
|
|
|
|
# define OPT_DNS_SEARCH htons_constant(24)
|
2021-04-13 19:59:47 +00:00
|
|
|
#define STR_NOTONLINK "Prefix not appropriate for link."
|
|
|
|
|
|
|
|
uint16_t l;
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
2023-01-06 00:43:12 +00:00
|
|
|
# define OPT_SIZE_CONV(x) (htons_constant(x))
|
2021-04-13 19:59:47 +00:00
|
|
|
#define OPT_SIZE(x) OPT_SIZE_CONV(sizeof(struct opt_##x) - \
|
|
|
|
sizeof(struct opt_hdr))
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
#define OPT_VSIZE(x) (sizeof(struct opt_##x) - \
|
|
|
|
sizeof(struct opt_hdr))
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_client_id - DHCPv6 Client Identifier option
|
|
|
|
* @hdr: Option header
|
|
|
|
* @duid: Client DUID, up to 128 bytes (cf. RFC 8415, 11.1.)
|
|
|
|
*/
|
|
|
|
struct opt_client_id {
|
|
|
|
struct opt_hdr hdr;
|
|
|
|
uint8_t duid[128];
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_server_id - DHCPv6 Server Identifier option
|
|
|
|
* @hdr: Option header
|
|
|
|
* @duid_type: Type of server DUID, network order
|
|
|
|
* @duid_hw: IANA hardware type, network order
|
|
|
|
* @duid_time: Time reference, network order
|
|
|
|
* @duid_lladdr: Link-layer address (MAC address)
|
|
|
|
*/
|
|
|
|
struct opt_server_id {
|
|
|
|
struct opt_hdr hdr;
|
|
|
|
uint16_t duid_type;
|
|
|
|
#define DUID_TYPE_LLT 1
|
|
|
|
|
|
|
|
uint16_t duid_hw;
|
|
|
|
uint32_t duid_time;
|
|
|
|
uint8_t duid_lladdr[ETH_ALEN];
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__ ((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
2023-01-06 00:43:12 +00:00
|
|
|
#define SERVER_ID { \
|
2021-10-19 17:18:04 +00:00
|
|
|
{ OPT_SERVERID, OPT_SIZE(server_id) }, \
|
2023-01-06 00:43:12 +00:00
|
|
|
htons_constant(DUID_TYPE_LLT), \
|
|
|
|
htons_constant(ARPHRD_ETHER), 0, { 0 } \
|
2021-10-19 17:18:04 +00:00
|
|
|
}
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_ia_na - Identity Association for Non-temporary Addresses Option
|
|
|
|
* @hdr: Option header
|
|
|
|
* @iaid: Unique identifier for IA_NA, network order
|
|
|
|
* @t1: Rebind interval for this server (always infinity)
|
|
|
|
* @t2: Rebind interval for any server (always infinity)
|
|
|
|
*/
|
|
|
|
struct opt_ia_na {
|
|
|
|
struct opt_hdr hdr;
|
|
|
|
uint32_t iaid;
|
|
|
|
uint32_t t1;
|
|
|
|
uint32_t t2;
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_ia_ta - Identity Association for Temporary Addresses Option
|
|
|
|
* @hdr: Option header
|
|
|
|
* @iaid: Unique identifier for IA_TA, network order
|
|
|
|
*/
|
|
|
|
struct opt_ia_ta {
|
|
|
|
struct opt_hdr hdr;
|
|
|
|
uint32_t iaid;
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_ia_addr - IA Address Option
|
|
|
|
* @hdr: Option header
|
|
|
|
* @addr: Leased IPv6 address
|
|
|
|
* @pref_lifetime: Preferred lifetime, network order (always infinity)
|
|
|
|
* @valid_lifetime: Valid lifetime, network order (always infinity)
|
|
|
|
*/
|
|
|
|
struct opt_ia_addr {
|
|
|
|
struct opt_hdr hdr;
|
|
|
|
struct in6_addr addr;
|
|
|
|
uint32_t pref_lifetime;
|
|
|
|
uint32_t valid_lifetime;
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_status_code - Status Code Option (used for NotOnLink error only)
|
|
|
|
* @hdr: Option header
|
|
|
|
* @code: Numeric code for status, network order
|
|
|
|
* @status_msg: Text string suitable for display, not NULL-terminated
|
|
|
|
*/
|
|
|
|
struct opt_status_code {
|
|
|
|
struct opt_hdr hdr;
|
|
|
|
uint16_t code;
|
|
|
|
char status_msg[sizeof(STR_NOTONLINK) - 1];
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_dns_servers - DNS Recursive Name Server option (RFC 3646)
|
|
|
|
* @hdr: Option header
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
* @addr: IPv6 DNS addresses
|
2021-04-13 19:59:47 +00:00
|
|
|
*/
|
|
|
|
struct opt_dns_servers {
|
|
|
|
struct opt_hdr hdr;
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
struct in6_addr addr[MAXNS];
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct opt_dns_servers - Domain Search List option (RFC 3646)
|
|
|
|
* @hdr: Option header
|
|
|
|
* @list: NULL-separated list of domain names
|
|
|
|
*/
|
|
|
|
struct opt_dns_search {
|
|
|
|
struct opt_hdr hdr;
|
|
|
|
char list[MAXDNSRCH * NS_MAXDNAME];
|
2022-09-28 04:33:17 +00:00
|
|
|
} __attribute__((packed));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* struct msg_hdr - DHCPv6 client/server message header
|
|
|
|
* @type: DHCP message type
|
|
|
|
* @xid: Transaction ID for message exchange
|
|
|
|
*/
|
|
|
|
struct msg_hdr {
|
|
|
|
uint32_t type:8;
|
|
|
|
#define TYPE_SOLICIT 1
|
|
|
|
#define TYPE_ADVERTISE 2
|
|
|
|
#define TYPE_REQUEST 3
|
|
|
|
#define TYPE_CONFIRM 4
|
|
|
|
#define TYPE_RENEW 5
|
|
|
|
#define TYPE_REBIND 6
|
|
|
|
#define TYPE_REPLY 7
|
|
|
|
#define TYPE_RELEASE 8
|
|
|
|
#define TYPE_DECLINE 9
|
|
|
|
#define TYPE_INFORMATION_REQUEST 11
|
|
|
|
|
|
|
|
uint32_t xid:24;
|
|
|
|
} __attribute__((__packed__));
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct resp_t - Normal advertise and reply message
|
|
|
|
* @hdr: DHCP message header
|
|
|
|
* @server_id: Server Identifier option
|
|
|
|
* @ia_na: Non-temporary Address option
|
|
|
|
* @ia_addr: Address for IA_NA
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
* @client_id: Client Identifier, variable length
|
|
|
|
* @dns_servers: DNS Recursive Name Server, here just for storage size
|
|
|
|
* @dns_search: Domain Search List, here just for storage size
|
2021-04-13 19:59:47 +00:00
|
|
|
*/
|
|
|
|
static struct resp_t {
|
|
|
|
struct msg_hdr hdr;
|
|
|
|
|
|
|
|
struct opt_server_id server_id;
|
|
|
|
struct opt_ia_na ia_na;
|
|
|
|
struct opt_ia_addr ia_addr;
|
|
|
|
struct opt_client_id client_id;
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
struct opt_dns_servers dns_servers;
|
|
|
|
struct opt_dns_search dns_search;
|
2021-04-13 19:59:47 +00:00
|
|
|
} __attribute__((__packed__)) resp = {
|
|
|
|
{ 0 },
|
2021-10-19 17:18:04 +00:00
|
|
|
SERVER_ID,
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
{ { OPT_IA_NA, OPT_SIZE_CONV(sizeof(struct opt_ia_na) +
|
|
|
|
sizeof(struct opt_ia_addr) -
|
|
|
|
sizeof(struct opt_hdr)) },
|
|
|
|
1, (uint32_t)~0U, (uint32_t)~0U
|
|
|
|
},
|
|
|
|
|
|
|
|
{ { OPT_IAAADR, OPT_SIZE(ia_addr) },
|
|
|
|
IN6ADDR_ANY_INIT, (uint32_t)~0U, (uint32_t)~0U
|
|
|
|
},
|
|
|
|
|
|
|
|
{ { OPT_CLIENTID, 0, },
|
|
|
|
{ 0 }
|
|
|
|
},
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
|
|
|
|
{ { OPT_DNS_SERVERS, 0, },
|
|
|
|
{ IN6ADDR_ANY_INIT }
|
|
|
|
},
|
|
|
|
|
|
|
|
{ { OPT_DNS_SEARCH, 0, },
|
|
|
|
{ 0 },
|
|
|
|
},
|
2021-04-13 19:59:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct opt_status_code sc_not_on_link = {
|
|
|
|
{ OPT_STATUS_CODE, OPT_SIZE(status_code), },
|
|
|
|
STATUS_NOTONLINK, STR_NOTONLINK
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* struct resp_not_on_link_t - NotOnLink error (mandated by RFC 8415, 18.3.2.)
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
* @hdr: DHCP message header
|
|
|
|
* @server_id: Server Identifier option
|
|
|
|
* @var: Payload: IA_NA from client, status code, client ID
|
2021-04-13 19:59:47 +00:00
|
|
|
*/
|
|
|
|
static struct resp_not_on_link_t {
|
|
|
|
struct msg_hdr hdr;
|
|
|
|
|
|
|
|
struct opt_server_id server_id;
|
|
|
|
|
|
|
|
uint8_t var[sizeof(struct opt_ia_na) + sizeof(struct opt_status_code) +
|
|
|
|
sizeof(struct opt_client_id)];
|
|
|
|
} __attribute__((__packed__)) resp_not_on_link = {
|
|
|
|
{ TYPE_REPLY, 0 },
|
2021-10-19 17:18:04 +00:00
|
|
|
SERVER_ID,
|
2021-04-13 19:59:47 +00:00
|
|
|
{ 0, },
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* dhcpv6_opt() - Get option from DHCPv6 message
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
* @p: Packet pool, single packet with UDP header
|
|
|
|
* @offset: Offset to look at, 0: end of header, set to option start
|
|
|
|
* @type: Option type to look up, network order
|
2021-04-13 19:59:47 +00:00
|
|
|
*
|
|
|
|
* Return: pointer to option header, or NULL on malformed or missing option
|
|
|
|
*/
|
2022-03-26 06:23:21 +00:00
|
|
|
static struct opt_hdr *dhcpv6_opt(const struct pool *p, size_t *offset,
|
|
|
|
uint16_t type)
|
2021-04-13 19:59:47 +00:00
|
|
|
{
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
struct opt_hdr *o;
|
|
|
|
size_t left;
|
2021-09-01 14:00:19 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
if (!*offset)
|
|
|
|
*offset = sizeof(struct udphdr) + sizeof(struct msg_hdr);
|
|
|
|
|
|
|
|
while ((o = packet_get_try(p, 0, *offset, sizeof(*o), &left))) {
|
|
|
|
unsigned int opt_len = ntohs(o->l) + sizeof(*o);
|
2021-04-13 19:59:47 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
if (ntohs(o->l) > left)
|
|
|
|
return NULL;
|
2021-04-22 00:30:20 +00:00
|
|
|
|
2021-04-13 19:59:47 +00:00
|
|
|
if (o->t == type)
|
|
|
|
return o;
|
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
*offset += opt_len;
|
2021-04-13 19:59:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* dhcpv6_ia_notonlink() - Check if any IA contains non-appropriate addresses
|
2022-03-26 06:23:21 +00:00
|
|
|
* @p: Packet pool, single packet starting from UDP header
|
|
|
|
* @la: Address we want to lease to the client
|
2021-04-13 19:59:47 +00:00
|
|
|
*
|
|
|
|
* Return: pointer to non-appropriate IA_NA or IA_TA, if any, NULL otherwise
|
|
|
|
*/
|
2022-03-26 06:23:21 +00:00
|
|
|
static struct opt_hdr *dhcpv6_ia_notonlink(const struct pool *p,
|
|
|
|
struct in6_addr *la)
|
2021-04-13 19:59:47 +00:00
|
|
|
{
|
2024-11-07 16:47:08 +00:00
|
|
|
int ia_types[2] = { OPT_IA_NA, OPT_IA_TA }, *ia_type;
|
|
|
|
const struct opt_ia_addr *opt_addr;
|
2021-04-21 15:15:23 +00:00
|
|
|
char buf[INET6_ADDRSTRLEN];
|
2022-09-28 04:33:17 +00:00
|
|
|
struct in6_addr req_addr;
|
2024-08-21 04:20:00 +00:00
|
|
|
const struct opt_hdr *h;
|
|
|
|
struct opt_hdr *ia;
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
size_t offset;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
2024-11-07 16:47:08 +00:00
|
|
|
foreach(ia_type, ia_types) {
|
|
|
|
offset = 0;
|
|
|
|
while ((ia = dhcpv6_opt(p, &offset, *ia_type))) {
|
|
|
|
if (ntohs(ia->l) < OPT_VSIZE(ia_na))
|
|
|
|
return NULL;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
2024-11-07 16:47:08 +00:00
|
|
|
offset += sizeof(struct opt_ia_na);
|
2021-09-01 14:00:19 +00:00
|
|
|
|
2024-11-07 16:47:08 +00:00
|
|
|
while ((h = dhcpv6_opt(p, &offset, OPT_IAAADR))) {
|
|
|
|
if (ntohs(h->l) != OPT_VSIZE(ia_addr))
|
|
|
|
return NULL;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
2024-11-07 16:47:08 +00:00
|
|
|
opt_addr = (const struct opt_ia_addr *)h;
|
|
|
|
req_addr = opt_addr->addr;
|
|
|
|
if (!IN6_ARE_ADDR_EQUAL(la, &req_addr))
|
|
|
|
goto err;
|
2021-04-21 15:15:23 +00:00
|
|
|
|
2024-11-07 16:47:08 +00:00
|
|
|
offset += sizeof(struct opt_ia_addr);
|
2021-04-21 15:15:23 +00:00
|
|
|
}
|
2021-04-13 19:59:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
2024-11-07 16:47:08 +00:00
|
|
|
|
|
|
|
err:
|
|
|
|
info("DHCPv6: requested address %s not on link",
|
|
|
|
inet_ntop(AF_INET6, &req_addr, buf, sizeof(buf)));
|
|
|
|
return ia;
|
2021-04-13 19:59:47 +00:00
|
|
|
}
|
|
|
|
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
/**
|
|
|
|
* dhcpv6_dns_fill() - Fill in DNS Servers and Domain Search list options
|
|
|
|
* @c: Execution context
|
|
|
|
* @buf: Response message buffer where options will be appended
|
|
|
|
* @offset: Offset in message buffer for new options
|
|
|
|
*
|
|
|
|
* Return: updated length of response message buffer.
|
|
|
|
*/
|
2022-03-26 06:23:21 +00:00
|
|
|
static size_t dhcpv6_dns_fill(const struct ctx *c, char *buf, int offset)
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
{
|
|
|
|
struct opt_dns_servers *srv = NULL;
|
|
|
|
struct opt_dns_search *srch = NULL;
|
2021-10-19 17:18:04 +00:00
|
|
|
char *p = NULL;
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
int i;
|
|
|
|
|
conf, udp: Introduce basic DNS forwarding
For compatibility with libslirp/slirp4netns users: introduce a
mechanism to map, in the UDP routines, an address facing guest or
namespace to the first IPv4 or IPv6 address resulting from
configuration as resolver. This can be enabled with the new
--dns-forward option.
This implies that sourcing and using DNS addresses and search lists,
passed via command line or read from /etc/resolv.conf, is not bound
anymore to DHCP/DHCPv6/NDP usage: for example, pasta users might just
want to use addresses from /etc/resolv.conf as mapping target, while
not passing DNS options via DHCP.
Reflect this in all the involved code paths by differentiating
DHCP/DHCPv6/NDP usage from DNS configuration per se, and in the new
options --dhcp-dns, --dhcp-search for pasta, and --no-dhcp-dns,
--no-dhcp-search for passt.
This should be the last bit to enable substantial compatibility
between slirp4netns.sh and slirp4netns(1): pass the --dns-forward
option from the script too.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-02-18 03:03:53 +00:00
|
|
|
if (c->no_dhcp_dns)
|
|
|
|
goto search;
|
|
|
|
|
conf, udp: Drop mostly duplicated dns_send arrays, rename related fields
Given that we use just the first valid DNS resolver address
configured, or read from resolv.conf(5) on the host, to forward DNS
queries to, in case --dns-forward is used, we don't need to duplicate
dns[] to dns_send[]:
- rename dns_send[] back to dns[]: those are the resolvers we
advertise to the guest/container
- for forwarding purposes, instead of dns[], use a single field (for
each protocol version): dns_host
- and rename dns_fwd to dns_match, so that it's clear this is the
address we are matching DNS queries against, to decide if they need
to be forwarded
Suggested-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
2022-11-10 19:30:03 +00:00
|
|
|
for (i = 0; !IN6_IS_ADDR_UNSPECIFIED(&c->ip6.dns[i]); i++) {
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
if (!i) {
|
|
|
|
srv = (struct opt_dns_servers *)(buf + offset);
|
|
|
|
offset += sizeof(struct opt_hdr);
|
|
|
|
srv->hdr.t = OPT_DNS_SERVERS;
|
|
|
|
srv->hdr.l = 0;
|
|
|
|
}
|
|
|
|
|
2024-08-21 04:20:00 +00:00
|
|
|
srv->addr[i] = c->ip6.dns[i];
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
srv->hdr.l += sizeof(srv->addr[i]);
|
|
|
|
offset += sizeof(srv->addr[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (srv)
|
|
|
|
srv->hdr.l = htons(srv->hdr.l);
|
|
|
|
|
conf, udp: Introduce basic DNS forwarding
For compatibility with libslirp/slirp4netns users: introduce a
mechanism to map, in the UDP routines, an address facing guest or
namespace to the first IPv4 or IPv6 address resulting from
configuration as resolver. This can be enabled with the new
--dns-forward option.
This implies that sourcing and using DNS addresses and search lists,
passed via command line or read from /etc/resolv.conf, is not bound
anymore to DHCP/DHCPv6/NDP usage: for example, pasta users might just
want to use addresses from /etc/resolv.conf as mapping target, while
not passing DNS options via DHCP.
Reflect this in all the involved code paths by differentiating
DHCP/DHCPv6/NDP usage from DNS configuration per se, and in the new
options --dhcp-dns, --dhcp-search for pasta, and --no-dhcp-dns,
--no-dhcp-search for passt.
This should be the last bit to enable substantial compatibility
between slirp4netns.sh and slirp4netns(1): pass the --dns-forward
option from the script too.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-02-18 03:03:53 +00:00
|
|
|
search:
|
|
|
|
if (c->no_dhcp_dns_search)
|
|
|
|
return offset;
|
|
|
|
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
for (i = 0; *c->dns_search[i].n; i++) {
|
dhcpv6: Properly separate domain names in search list
To prepare the DHCPv6 domain search list option, we go over the
flattened list of domains, and replace both dots and zero bytes with a
counter of bytes in the next label, implementing the encoding
specified by section 3.1 of RFC 1035.
If there are multiple domains in the list, however, zero bytes serve
as markers for the end of a domain name, and we'll replace them with
the length of the first label of the next domain, plus one. This is
wrong. We should only convert the dots before the labels.
To distinguish between label separators and domain names separators,
for simplicity, introduce a dot before the first label of every
domain we copy to form the list. All dots are then replaced by label
lengths, and separators (zero bytes) remain as they are.
As we do this, we need to make sure we don't replace the trailing
dot, if present: that's already a separator. Skip copying it, and
just add separators as needed.
Now that we don't copy those, though, we might end up with
zero-length domains: skip them, as they're meaningless anyway.
And as we might skip domains, we can't use the index 'i' to check if
we're at the beginning of the option -- use 'srch' instead.
This is very similar to how we prepare the list for NDP option 31,
except that we don't need padding (RFC 8106, 5.2) here, and we should
refactor this into common functions, but it probably makes sense to
rework the NDP responder (https://bugs.passt.top/show_bug.cgi?id=21)
first.
Reported-by: Sebastian Mitterle <smitterl@redhat.com>
Link: https://bugs.passt.top/show_bug.cgi?id=75
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2023-09-20 14:39:11 +00:00
|
|
|
size_t name_len = strlen(c->dns_search[i].n);
|
|
|
|
|
|
|
|
/* We already append separators, don't duplicate if present */
|
|
|
|
if (c->dns_search[i].n[name_len - 1] == '.')
|
|
|
|
name_len--;
|
|
|
|
|
|
|
|
/* Skip root-only search domains */
|
|
|
|
if (!name_len)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!srch) {
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
srch = (struct opt_dns_search *)(buf + offset);
|
|
|
|
offset += sizeof(struct opt_hdr);
|
|
|
|
srch->hdr.t = OPT_DNS_SEARCH;
|
|
|
|
srch->hdr.l = 0;
|
|
|
|
p = srch->list;
|
|
|
|
}
|
|
|
|
|
dhcpv6: Properly separate domain names in search list
To prepare the DHCPv6 domain search list option, we go over the
flattened list of domains, and replace both dots and zero bytes with a
counter of bytes in the next label, implementing the encoding
specified by section 3.1 of RFC 1035.
If there are multiple domains in the list, however, zero bytes serve
as markers for the end of a domain name, and we'll replace them with
the length of the first label of the next domain, plus one. This is
wrong. We should only convert the dots before the labels.
To distinguish between label separators and domain names separators,
for simplicity, introduce a dot before the first label of every
domain we copy to form the list. All dots are then replaced by label
lengths, and separators (zero bytes) remain as they are.
As we do this, we need to make sure we don't replace the trailing
dot, if present: that's already a separator. Skip copying it, and
just add separators as needed.
Now that we don't copy those, though, we might end up with
zero-length domains: skip them, as they're meaningless anyway.
And as we might skip domains, we can't use the index 'i' to check if
we're at the beginning of the option -- use 'srch' instead.
This is very similar to how we prepare the list for NDP option 31,
except that we don't need padding (RFC 8106, 5.2) here, and we should
refactor this into common functions, but it probably makes sense to
rework the NDP responder (https://bugs.passt.top/show_bug.cgi?id=21)
first.
Reported-by: Sebastian Mitterle <smitterl@redhat.com>
Link: https://bugs.passt.top/show_bug.cgi?id=75
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2023-09-20 14:39:11 +00:00
|
|
|
*p = '.';
|
|
|
|
p = stpncpy(p + 1, c->dns_search[i].n, name_len);
|
|
|
|
p++;
|
|
|
|
srch->hdr.l += name_len + 2;
|
|
|
|
offset += name_len + 2;
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (srch) {
|
|
|
|
for (i = 0; i < srch->hdr.l; i++) {
|
dhcpv6: Properly separate domain names in search list
To prepare the DHCPv6 domain search list option, we go over the
flattened list of domains, and replace both dots and zero bytes with a
counter of bytes in the next label, implementing the encoding
specified by section 3.1 of RFC 1035.
If there are multiple domains in the list, however, zero bytes serve
as markers for the end of a domain name, and we'll replace them with
the length of the first label of the next domain, plus one. This is
wrong. We should only convert the dots before the labels.
To distinguish between label separators and domain names separators,
for simplicity, introduce a dot before the first label of every
domain we copy to form the list. All dots are then replaced by label
lengths, and separators (zero bytes) remain as they are.
As we do this, we need to make sure we don't replace the trailing
dot, if present: that's already a separator. Skip copying it, and
just add separators as needed.
Now that we don't copy those, though, we might end up with
zero-length domains: skip them, as they're meaningless anyway.
And as we might skip domains, we can't use the index 'i' to check if
we're at the beginning of the option -- use 'srch' instead.
This is very similar to how we prepare the list for NDP option 31,
except that we don't need padding (RFC 8106, 5.2) here, and we should
refactor this into common functions, but it probably makes sense to
rework the NDP responder (https://bugs.passt.top/show_bug.cgi?id=21)
first.
Reported-by: Sebastian Mitterle <smitterl@redhat.com>
Link: https://bugs.passt.top/show_bug.cgi?id=75
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2023-09-20 14:39:11 +00:00
|
|
|
if (srch->list[i] == '.') {
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
srch->list[i] = strcspn(srch->list + i + 1,
|
|
|
|
".");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
srch->hdr.l = htons(srch->hdr.l);
|
|
|
|
}
|
|
|
|
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2021-04-13 19:59:47 +00:00
|
|
|
/**
|
|
|
|
* dhcpv6() - Check if this is a DHCPv6 message, reply as needed
|
|
|
|
* @c: Execution context
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
* @p: Packet pool, single packet starting from UDP header
|
|
|
|
* @saddr: Source IPv6 address of original message
|
|
|
|
* @daddr: Destination IPv6 address of original message
|
2021-04-13 19:59:47 +00:00
|
|
|
*
|
|
|
|
* Return: 0 if it's not a DHCPv6 message, 1 if handled, -1 on failure
|
|
|
|
*/
|
2022-03-26 06:23:21 +00:00
|
|
|
int dhcpv6(struct ctx *c, const struct pool *p,
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
const struct in6_addr *saddr, const struct in6_addr *daddr)
|
2021-04-13 19:59:47 +00:00
|
|
|
{
|
2024-11-07 17:08:46 +00:00
|
|
|
const struct opt_hdr *client_id, *server_id, *ia;
|
2024-01-15 06:39:43 +00:00
|
|
|
const struct in6_addr *src;
|
|
|
|
const struct msg_hdr *mh;
|
|
|
|
const struct udphdr *uh;
|
2024-11-07 17:08:46 +00:00
|
|
|
struct opt_hdr *bad_ia;
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
size_t mlen, n;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
uh = packet_get(p, 0, 0, sizeof(*uh), &mlen);
|
|
|
|
if (!uh)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (uh->dest != htons(547))
|
2021-04-13 19:59:47 +00:00
|
|
|
return 0;
|
|
|
|
|
2021-08-12 13:42:43 +00:00
|
|
|
if (c->no_dhcpv6)
|
|
|
|
return 1;
|
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
if (!IN6_IS_ADDR_MULTICAST(daddr))
|
2021-04-13 19:59:47 +00:00
|
|
|
return -1;
|
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
if (mlen + sizeof(*uh) != ntohs(uh->len) || mlen < sizeof(*mh))
|
2021-04-13 19:59:47 +00:00
|
|
|
return -1;
|
|
|
|
|
2022-07-22 05:31:18 +00:00
|
|
|
c->ip6.addr_ll_seen = *saddr;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
2024-08-21 04:20:11 +00:00
|
|
|
src = &c->ip6.our_tap_ll;
|
2021-10-20 09:10:23 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
mh = packet_get(p, 0, sizeof(*uh), sizeof(*mh), NULL);
|
|
|
|
if (!mh)
|
|
|
|
return -1;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
client_id = dhcpv6_opt(p, &(size_t){ 0 }, OPT_CLIENTID);
|
|
|
|
if (!client_id || ntohs(client_id->l) > OPT_VSIZE(client_id))
|
2021-04-13 19:59:47 +00:00
|
|
|
return -1;
|
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
server_id = dhcpv6_opt(p, &(size_t){ 0 }, OPT_SERVERID);
|
|
|
|
if (server_id && ntohs(server_id->l) != OPT_VSIZE(server_id))
|
|
|
|
return -1;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
ia = dhcpv6_opt(p, &(size_t){ 0 }, OPT_IA_NA);
|
|
|
|
if (ia && ntohs(ia->l) < MIN(OPT_VSIZE(ia_na), OPT_VSIZE(ia_ta)))
|
2021-04-13 19:59:47 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
resp.hdr.type = TYPE_REPLY;
|
|
|
|
switch (mh->type) {
|
|
|
|
case TYPE_REQUEST:
|
|
|
|
case TYPE_RENEW:
|
|
|
|
if (!server_id ||
|
|
|
|
memcmp(&resp.server_id, server_id, sizeof(resp.server_id)))
|
|
|
|
return -1;
|
|
|
|
/* Falls through */
|
|
|
|
case TYPE_CONFIRM:
|
|
|
|
if (mh->type == TYPE_CONFIRM && server_id)
|
|
|
|
return -1;
|
|
|
|
|
2022-07-22 05:31:18 +00:00
|
|
|
if ((bad_ia = dhcpv6_ia_notonlink(p, &c->ip6.addr))) {
|
2021-04-21 15:15:23 +00:00
|
|
|
info("DHCPv6: received CONFIRM with inappropriate IA,"
|
|
|
|
" sending NotOnLink status in REPLY");
|
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
bad_ia->l = htons(OPT_VSIZE(ia_na) +
|
2021-04-21 15:15:23 +00:00
|
|
|
sizeof(sc_not_on_link));
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
n = sizeof(struct opt_ia_na);
|
2021-04-21 15:15:23 +00:00
|
|
|
memcpy(resp_not_on_link.var, bad_ia, n);
|
2021-04-13 19:59:47 +00:00
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
memcpy(resp_not_on_link.var + n,
|
|
|
|
&sc_not_on_link, sizeof(sc_not_on_link));
|
2021-04-13 19:59:47 +00:00
|
|
|
n += sizeof(sc_not_on_link);
|
|
|
|
|
2021-04-21 15:15:23 +00:00
|
|
|
memcpy(resp_not_on_link.var + n, client_id,
|
|
|
|
sizeof(struct opt_hdr) + ntohs(client_id->l));
|
|
|
|
n += sizeof(struct opt_hdr) + ntohs(client_id->l);
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
n = offsetof(struct resp_not_on_link_t, var) + n;
|
|
|
|
|
|
|
|
resp_not_on_link.hdr.xid = mh->xid;
|
|
|
|
|
2022-10-19 00:43:53 +00:00
|
|
|
tap_udp6_send(c, src, 547, tap_ip6_daddr(c, src), 546,
|
|
|
|
mh->xid, &resp_not_on_link, n);
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
info("DHCPv6: received REQUEST/RENEW/CONFIRM, sending REPLY");
|
|
|
|
break;
|
|
|
|
case TYPE_INFORMATION_REQUEST:
|
|
|
|
if (server_id &&
|
|
|
|
memcmp(&resp.server_id, server_id, sizeof(resp.server_id)))
|
|
|
|
return -1;
|
|
|
|
|
treewide: Packet abstraction with mandatory boundary checks
Implement a packet abstraction providing boundary and size checks
based on packet descriptors: packets stored in a buffer can be queued
into a pool (without storage of its own), and data can be retrieved
referring to an index in the pool, specifying offset and length.
Checks ensure data is not read outside the boundaries of buffer and
descriptors, and that packets added to a pool are within the buffer
range with valid offset and indices.
This implies a wider rework: usage of the "queueing" part of the
abstraction mostly affects tap_handler_{passt,pasta}() functions and
their callees, while the "fetching" part affects all the guest or tap
facing implementations: TCP, UDP, ICMP, ARP, NDP, DHCP and DHCPv6
handlers.
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2022-03-25 12:02:47 +00:00
|
|
|
if (ia || dhcpv6_opt(p, &(size_t){ 0 }, OPT_IA_TA))
|
2021-04-13 19:59:47 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
info("DHCPv6: received INFORMATION_REQUEST, sending REPLY");
|
|
|
|
break;
|
|
|
|
case TYPE_REBIND:
|
|
|
|
if (!server_id ||
|
|
|
|
memcmp(&resp.server_id, server_id, sizeof(resp.server_id)))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
info("DHCPv6: received REBIND, sending REPLY");
|
|
|
|
break;
|
|
|
|
case TYPE_SOLICIT:
|
|
|
|
if (server_id)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
resp.hdr.type = TYPE_ADVERTISE;
|
|
|
|
|
|
|
|
info("DHCPv6: received SOLICIT, sending ADVERTISE");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (ia)
|
|
|
|
resp.ia_na.iaid = ((struct opt_ia_na *)ia)->iaid;
|
|
|
|
|
|
|
|
memcpy(&resp.client_id, client_id,
|
|
|
|
ntohs(client_id->l) + sizeof(struct opt_hdr));
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
|
|
|
|
n = offsetof(struct resp_t, client_id) +
|
|
|
|
sizeof(struct opt_hdr) + ntohs(client_id->l);
|
|
|
|
n = dhcpv6_dns_fill(c, (char *)&resp, n);
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
resp.hdr.xid = mh->xid;
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
|
2022-10-19 00:43:53 +00:00
|
|
|
tap_udp6_send(c, src, 547, tap_ip6_daddr(c, src), 546,
|
|
|
|
mh->xid, &resp, n);
|
2022-07-22 05:31:18 +00:00
|
|
|
c->ip6.addr_seen = c->ip6.addr;
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
dhcp, ndp, dhcpv6: Support for multiple DNS servers, search list
Add support for a variable amount of DNS servers, including zero,
from /etc/resolv.conf, in DHCP, NDP and DHCPv6 implementations.
Introduce support for domain search list for DHCP (RFC 3397),
NDP (RFC 8106), and DHCPv6 (RFC 3646), also sourced from
/etc/resolv.conf.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
2021-05-21 09:14:47 +00:00
|
|
|
* dhcpv6_init() - Initialise DUID and addresses for DHCPv6 server
|
2021-04-13 19:59:47 +00:00
|
|
|
* @c: Execution context
|
|
|
|
*/
|
2022-03-26 06:23:21 +00:00
|
|
|
void dhcpv6_init(const struct ctx *c)
|
2021-04-13 19:59:47 +00:00
|
|
|
{
|
2021-10-13 23:21:29 +00:00
|
|
|
time_t y2k = 946684800; /* Epoch to 2000-01-01T00:00:00Z, no mktime() */
|
2021-04-13 19:59:47 +00:00
|
|
|
uint32_t duid_time;
|
|
|
|
|
2021-10-13 23:21:29 +00:00
|
|
|
duid_time = htonl(difftime(time(NULL), y2k));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
|
|
|
resp.server_id.duid_time = duid_time;
|
|
|
|
resp_not_on_link.server_id.duid_time = duid_time;
|
|
|
|
|
2024-08-21 04:19:59 +00:00
|
|
|
memcpy(resp.server_id.duid_lladdr,
|
|
|
|
c->our_tap_mac, sizeof(c->our_tap_mac));
|
|
|
|
memcpy(resp_not_on_link.server_id.duid_lladdr,
|
|
|
|
c->our_tap_mac, sizeof(c->our_tap_mac));
|
2021-04-13 19:59:47 +00:00
|
|
|
|
2022-07-22 05:31:18 +00:00
|
|
|
resp.ia_addr.addr = c->ip6.addr;
|
2021-04-13 19:59:47 +00:00
|
|
|
}
|