On Wed, 2014-08-06 at 11:22 -0500, Dan Williams wrote: > Like Infiniband. See RFC 4390 section 2.1 for details on DHCP > and Infiniband; chaddr is zeroed, hlen is set to 0, and htype > is set to ARPHRD_INFINIBAND because IB hardware addresses > are 20 bytes in length. > --- > NOTE: because of how dhcp_network_bind_raw_socket() does its packet > filter, it's not easy to change some of the checks it uses without > having callers pass the actual values into the function, which seems > redundant. Thus I opted for the current approach, but that does > add a warning about mixed declarations and code. Can anyone think > of a better way to do this? > > An possible improvement to sd_dhcp_client_set_mac() would be > keying the MAC address length off 'arp_type' instead of > specifying it explicitly.
Any comments on this approach Tom? (or anyone else?) Dan > src/libsystemd-network/dhcp-internal.h | 10 +++-- > src/libsystemd-network/dhcp-network.c | 39 +++++++++++++++---- > src/libsystemd-network/dhcp-packet.c | 8 ++-- > src/libsystemd-network/sd-dhcp-client.c | 63 > +++++++++++++++++++++++-------- > src/libsystemd-network/sd-dhcp-server.c | 6 +-- > src/libsystemd-network/test-dhcp-client.c | 14 +++++-- > src/libsystemd-network/test-dhcp-option.c | 2 +- > src/network/networkd-link.c | 9 ++++- > src/systemd/sd-dhcp-client.h | 4 +- > 9 files changed, 116 insertions(+), 39 deletions(-) > > diff --git a/src/libsystemd-network/dhcp-internal.h > b/src/libsystemd-network/dhcp-internal.h > index 1069c8a..d358a49 100644 > --- a/src/libsystemd-network/dhcp-internal.h > +++ b/src/libsystemd-network/dhcp-internal.h > @@ -20,22 +20,25 @@ > > You should have received a copy of the GNU Lesser General Public License > along with systemd; If not, see <http://www.gnu.org/licenses/>. > ***/ > > #include <stdint.h> > #include <linux/if_packet.h> > +#include <net/if_arp.h> > #include <net/ethernet.h> > > #include "socket-util.h" > > #include "sd-dhcp-client.h" > #include "dhcp-protocol.h" > > -int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, > uint32_t xid, struct ether_addr mac_addr); > +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, > + uint32_t xid, const uint8_t *mac_addr, > + size_t mac_addr_len, uint16_t arp_type); > int dhcp_network_bind_udp_socket(be32_t address, uint16_t port); > int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, > const void *packet, size_t len); > int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, > const void *packet, size_t len); > > int dhcp_option_append(DHCPMessage *message, size_t size, size_t *offset, > uint8_t overload, > @@ -43,16 +46,17 @@ int dhcp_option_append(DHCPMessage *message, size_t size, > size_t *offset, uint8_ > > typedef int (*dhcp_option_cb_t)(uint8_t code, uint8_t len, > const uint8_t *option, void *user_data); > > int dhcp_option_parse(DHCPMessage *message, size_t len, > dhcp_option_cb_t cb, void *user_data); > > -int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, > uint8_t type, > - size_t optlen, size_t *optoffset); > +int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, > + uint8_t type, uint16_t arp_type, size_t optlen, > + size_t *optoffset); > > uint16_t dhcp_packet_checksum(uint8_t *buf, size_t len); > > void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr, > uint16_t source, be32_t destination_addr, > uint16_t destination, uint16_t len); > > diff --git a/src/libsystemd-network/dhcp-network.c > b/src/libsystemd-network/dhcp-network.c > index 1ced5cf..4d82bcf 100644 > --- a/src/libsystemd-network/dhcp-network.c > +++ b/src/libsystemd-network/dhcp-network.c > @@ -18,26 +18,45 @@ > ***/ > > #include <errno.h> > #include <sys/types.h> > #include <sys/socket.h> > #include <string.h> > #include <linux/if_packet.h> > +#include <linux/if_infiniband.h> > #include <net/ethernet.h> > #include <net/if_arp.h> > #include <stdio.h> > #include <unistd.h> > #include <linux/filter.h> > > #include "socket-util.h" > > #include "dhcp-internal.h" > > +/* Default broadcast address for IPoIB */ > +static const uint8_t ib_bcast_addr[20] = { > + 0x00, 0xff, 0xff, 0xff, 0xff, 0x12, 0x40, 0x1b, > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0xff, 0xff, 0xff, 0xff > +}; > + > int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, > - uint32_t xid, struct ether_addr mac_addr) { > + uint32_t xid, const uint8_t *mac_addr, > + size_t mac_addr_len, uint16_t arp_type) { > + struct ether_addr eth_mac = { { 0, 0, 0, 0, 0, 0 } }; > + uint8_t dhcp_hlen = 0; > + > + assert_return(mac_addr_len > 0, -EINVAL); > + > + if (arp_type == ARPHRD_ETHER) { > + assert_return(mac_addr_len == ETH_ALEN, -EINVAL); > + memcpy(ð_mac, mac_addr, ETH_ALEN); > + dhcp_hlen = ETH_ALEN; > + } > > struct sock_filter filter[] = { > BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), > /* A <- packet length */ > BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(DHCPPacket), 1, > 0), /* packet >= DHCPPacket ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, > ip.protocol)), /* A <- IP protocol */ > BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 1, 0), > /* IP protocol == UDP ? */ > @@ -53,29 +72,29 @@ int dhcp_network_bind_raw_socket(int ifindex, union > sockaddr_union *link, > BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, > udp.dest)), /* A <- UDP destination port */ > BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_PORT_CLIENT, 1, 0), > /* UDP destination port == DHCP client port ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, > dhcp.op)), /* A <- DHCP op */ > BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, BOOTREPLY, 1, 0), > /* op == BOOTREPLY ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, > dhcp.htype)), /* A <- DHCP header type */ > - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ARPHRD_ETHER, 1, 0), > /* header type == ARPHRD_ETHER ? */ > + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arp_type, 1, 0), > /* header type == arp_type ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > BPF_STMT(BPF_LD + BPF_B + BPF_ABS, offsetof(DHCPPacket, > dhcp.hlen)), /* A <- mac address length */ > - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, ETHER_ADDR_LEN, 1, 0), > /* address length == ETHER_ADDR_LEN ? */ > + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, dhcp_hlen, 1, 0), > /* address length == dhcp_hlen ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, > dhcp.xid)), /* A <- client identifier */ > BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, xid, 1, 0), > /* client identifier == xid ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > - BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) > &mac_addr))), /* A <- 4 bytes of client's MAC */ > + BPF_STMT(BPF_LD + BPF_IMM, htobe32(*((unsigned int *) > ð_mac))), /* A <- 4 bytes of client's MAC */ > BPF_STMT(BPF_MISC + BPF_TAX, 0), > /* X <- A */ > BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, > dhcp.chaddr)), /* A <- 4 bytes of MAC from dhcp.chaddr */ > BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), > /* A xor X */ > BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), > /* A == 0 ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > - BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) > (((char *) &mac_addr) + 4)))), /* A <- remainder of client's MAC */ > + BPF_STMT(BPF_LD + BPF_IMM, htobe16(*((unsigned short *) > (((char *) ð_mac) + 4)))), /* A <- remainder of client's MAC */ > BPF_STMT(BPF_MISC + BPF_TAX, 0), > /* X <- A */ > BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(DHCPPacket, > dhcp.chaddr) + 4), /* A <- remainder of MAC from dhcp.chaddr */ > BPF_STMT(BPF_ALU + BPF_XOR + BPF_X, 0), > /* A xor X */ > BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 0, 1, 0), > /* A == 0 ? */ > BPF_STMT(BPF_RET + BPF_K, 0), > /* ignore */ > BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(DHCPPacket, > dhcp.magic)), /* A <- DHCP magic cookie */ > BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, DHCP_MAGIC_COOKIE, 1, > 0), /* cookie == DHCP magic cookie ? */ > @@ -103,16 +122,22 @@ int dhcp_network_bind_raw_socket(int ifindex, union > sockaddr_union *link, > r = setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &fprog, > sizeof(fprog)); > if (r < 0) > return -errno; > > link->ll.sll_family = AF_PACKET; > link->ll.sll_protocol = htons(ETH_P_IP); > link->ll.sll_ifindex = ifindex; > - link->ll.sll_halen = ETH_ALEN; > - memset(link->ll.sll_addr, 0xff, ETH_ALEN); > + link->ll.sll_hatype = htons(arp_type); > + link->ll.sll_halen = mac_addr_len; > + if (mac_addr_len == ETH_ALEN) > + memset(link->ll.sll_addr, 0xff, ETH_ALEN); > + else if (mac_addr_len == INFINIBAND_ALEN) > + memcpy(link->ll.sll_addr, ib_bcast_addr, sizeof > (ib_bcast_addr)); > + else > + assert_not_reached("unhandled hardware address length"); > > r = bind(s, &link->sa, sizeof(link->ll)); > if (r < 0) > return -errno; > > r = s; > s = -1; > diff --git a/src/libsystemd-network/dhcp-packet.c > b/src/libsystemd-network/dhcp-packet.c > index 9f850fd..7581dae 100644 > --- a/src/libsystemd-network/dhcp-packet.c > +++ b/src/libsystemd-network/dhcp-packet.c > @@ -34,23 +34,25 @@ > #include "dhcp-internal.h" > #include "sd-dhcp-lease.h" > #include "sd-dhcp-client.h" > > #define DHCP_CLIENT_MIN_OPTIONS_SIZE 312 > > int dhcp_message_init(DHCPMessage *message, uint8_t op, uint32_t xid, > - uint8_t type, size_t optlen, size_t *optoffset) { > + uint8_t type, uint16_t arp_type, size_t optlen, > + size_t *optoffset) { > size_t offset = 0; > int r; > > assert(op == BOOTREQUEST || op == BOOTREPLY); > + assert(arp_type == ARPHRD_ETHER || arp_type == ARPHRD_INFINIBAND); > > message->op = op; > - message->htype = ARPHRD_ETHER; > - message->hlen = ETHER_ADDR_LEN; > + message->htype = arp_type; > + message->hlen = (arp_type == ARPHRD_ETHER) ? ETHER_ADDR_LEN : 0; > message->xid = htobe32(xid); > message->magic = htobe32(DHCP_MAGIC_COOKIE); > > r = dhcp_option_append(message, optlen, &offset, 0, > DHCP_OPTION_MESSAGE_TYPE, 1, &type); > if (r < 0) > return r; > diff --git a/src/libsystemd-network/sd-dhcp-client.c > b/src/libsystemd-network/sd-dhcp-client.c > index f5910d9..b36a18d 100644 > --- a/src/libsystemd-network/sd-dhcp-client.c > +++ b/src/libsystemd-network/sd-dhcp-client.c > @@ -33,14 +33,16 @@ > #include "async.h" > > #include "dhcp-protocol.h" > #include "dhcp-internal.h" > #include "dhcp-lease-internal.h" > #include "sd-dhcp-client.h" > > +#define MAX_MAC_ADDR_LEN 20 /* INFINIBAND_ALEN */ > + > struct sd_dhcp_client { > RefCount n_ref; > > DHCPState state; > sd_event *event; > int event_priority; > sd_event_source *timeout_resend; > @@ -53,14 +55,17 @@ struct sd_dhcp_client { > size_t req_opts_allocated; > size_t req_opts_size; > be32_t last_addr; > struct { > uint8_t type; > struct ether_addr mac_addr; > } _packed_ client_id; > + uint8_t mac_addr[MAX_MAC_ADDR_LEN]; > + size_t mac_addr_len; > + uint16_t arp_type; > char *hostname; > char *vendor_class_identifier; > uint32_t mtu; > uint32_t xid; > usec_t start_time; > uint16_t secs; > unsigned int attempt; > @@ -159,32 +164,39 @@ int sd_dhcp_client_set_index(sd_dhcp_client *client, > int interface_index) { > assert_return(interface_index > 0, -EINVAL); > > client->index = interface_index; > > return 0; > } > > -int sd_dhcp_client_set_mac(sd_dhcp_client *client, > - const struct ether_addr *addr) { > +int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, > + size_t addr_len, uint16_t arp_type) { > DHCP_CLIENT_DONT_DESTROY(client); > bool need_restart = false; > > assert_return(client, -EINVAL); > assert_return(addr, -EINVAL); > + assert_return(addr_len > 0 && addr_len <= MAX_MAC_ADDR_LEN, -EINVAL); > + assert_return(arp_type > 0, -EINVAL); > > - if (memcmp(&client->client_id.mac_addr, addr, ETH_ALEN) == 0) > + if (client->mac_addr_len == addr_len && > + memcmp(&client->mac_addr, addr, addr_len) == 0) > return 0; > > if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { > log_dhcp_client(client, "Changing MAC address on running > DHCP " > "client, restarting"); > need_restart = true; > client_stop(client, DHCP_EVENT_STOP); > } > > + memcpy(&client->mac_addr, addr, addr_len); > + client->mac_addr_len = addr_len; > + client->arp_type = arp_type; > + > memcpy(&client->client_id.mac_addr, addr, ETH_ALEN); > client->client_id.type = 0x01; > > if (need_restart && client->state != DHCP_STATE_STOPPED) > sd_dhcp_client_start(client); > > return 0; > @@ -314,15 +326,15 @@ static int client_message_init(sd_dhcp_client *client, > DHCPPacket **ret, > size = sizeof(DHCPPacket) + optlen; > > packet = malloc0(size); > if (!packet) > return -ENOMEM; > > r = dhcp_message_init(&packet->dhcp, BOOTREQUEST, client->xid, type, > - optlen, &optoffset); > + client->arp_type, optlen, &optoffset); > if (r < 0) > return r; > > /* Although 'secs' field is a SHOULD in RFC 2131, certain DHCP > servers > refuse to issue an DHCP lease if 'secs' is set to zero */ > packet->dhcp.secs = htobe16(client->secs); > > @@ -338,17 +350,20 @@ static int client_message_init(sd_dhcp_client *client, > DHCPPacket **ret, > needs this to be disabled as broadcasts are filteretd, so this > needs to be configurable */ > if (client->request_broadcast) > packet->dhcp.flags = htobe16(0x8000); > > /* RFC2132 section 4.1.1: > The client MUST include its hardware address in the ’chaddr’ > field, if > - necessary for delivery of DHCP reply messages. > + necessary for delivery of DHCP reply messages. Non-Ethernet > + interfaces will leave 'chaddr' empty and use the client identifier > + instead (eg, RFC 4390 section 2.1). > */ > - memcpy(&packet->dhcp.chaddr, &client->client_id.mac_addr, ETH_ALEN); > + if (client->mac_addr_len == ETH_ALEN) > + memcpy(&packet->dhcp.chaddr, &client->mac_addr, ETH_ALEN); > > /* Some DHCP servers will refuse to issue an DHCP lease if the Client > Identifier option is not set */ > r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0, > DHCP_OPTION_CLIENT_IDENTIFIER, > sizeof(client->client_id), > &client->client_id); > if (r < 0) > @@ -824,15 +839,17 @@ static int client_start(sd_dhcp_client *client) { > assert_return(client->fd < 0, -EBUSY); > assert_return(client->xid == 0, -EINVAL); > assert_return(client->state == DHCP_STATE_INIT || > client->state == DHCP_STATE_INIT_REBOOT, -EBUSY); > > client->xid = random_u32(); > > - r = dhcp_network_bind_raw_socket(client->index, &client->link, > client->xid, client->client_id.mac_addr); > + r = dhcp_network_bind_raw_socket(client->index, &client->link, > + client->xid, client->mac_addr, > + client->mac_addr_len, > client->arp_type); > if (r < 0) { > client_stop(client, r); > return r; > } > client->fd = r; > > if (client->state == DHCP_STATE_INIT) { > @@ -868,15 +885,17 @@ static int client_timeout_t2(sd_event_source *s, > uint64_t usec, void *userdata) > > client->receive_message = > sd_event_source_unref(client->receive_message); > client->fd = asynchronous_close(client->fd); > > client->state = DHCP_STATE_REBINDING; > client->attempt = 1; > > - r = dhcp_network_bind_raw_socket(client->index, &client->link, > client->xid, client->client_id.mac_addr); > + r = dhcp_network_bind_raw_socket(client->index, &client->link, > + client->xid, client->mac_addr, > + client->mac_addr_len, > client->arp_type); > if (r < 0) { > client_stop(client, r); > return 0; > } > client->fd = r; > > return client_initialize_events(client, client_receive_message_raw); > @@ -1292,14 +1311,17 @@ error: > } > > static int client_receive_message_udp(sd_event_source *s, int fd, > uint32_t revents, void *userdata) { > sd_dhcp_client *client = userdata; > _cleanup_free_ DHCPMessage *message = NULL; > int buflen = 0, len, r; > + const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } }; > + const struct ether_addr *expected_chaddr = NULL; > + uint8_t expected_hlen = 0; > > assert(s); > assert(client); > > r = ioctl(fd, FIONREAD, &buflen); > if (r < 0) > return r; > @@ -1328,21 +1350,34 @@ static int client_receive_message_udp(sd_event_source > *s, int fd, > } > > if (message->op != BOOTREPLY) { > log_dhcp_client(client, "not a BOOTREPLY message: ignoring"); > return 0; > } > > - if (message->htype != ARPHRD_ETHER || message->hlen != > ETHER_ADDR_LEN) { > - log_dhcp_client(client, "not an ethernet packet"); > + if (message->htype != client->arp_type) { > + log_dhcp_client(client, "packet type does not match client > type"); > return 0; > } > > - if (memcmp(&message->chaddr[0], &client->client_id.mac_addr, > - ETH_ALEN)) { > + if (client->arp_type == ARPHRD_ETHER) { > + expected_hlen = ETH_ALEN; > + expected_chaddr = (const struct ether_addr *) > &client->mac_addr; > + } else { > + /* Non-ethernet links expect zero chaddr */ > + expected_hlen = 0; > + expected_chaddr = &zero_mac; > + } > + > + if (message->hlen != expected_hlen) { > + log_dhcp_client(client, "unexpected packet hlen %d", > message->hlen); > + return 0; > + } > + > + if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) { > log_dhcp_client(client, "received chaddr does not match " > "expected: ignoring"); > return 0; > } > > if (client->state != DHCP_STATE_BOUND && > be32toh(message->xid) != client->xid) { > @@ -1429,17 +1464,15 @@ int sd_dhcp_client_start(sd_dhcp_client *client) { > return r; > > if (client->last_addr) > client->state = DHCP_STATE_INIT_REBOOT; > > r = client_start(client); > if (r >= 0) > - log_dhcp_client(client, "STARTED on ifindex %u with address > %s", > - client->index, > - ether_ntoa(&client->client_id.mac_addr)); > + log_dhcp_client(client, "STARTED on ifindex %u", > client->index); > > return r; > } > > int sd_dhcp_client_stop(sd_dhcp_client *client) { > DHCP_CLIENT_DONT_DESTROY(client); > > diff --git a/src/libsystemd-network/sd-dhcp-server.c > b/src/libsystemd-network/sd-dhcp-server.c > index c224aa1..79b104c 100644 > --- a/src/libsystemd-network/sd-dhcp-server.c > +++ b/src/libsystemd-network/sd-dhcp-server.c > @@ -375,15 +375,15 @@ static int server_message_init(sd_dhcp_server *server, > DHCPPacket **ret, > assert(IN_SET(type, DHCP_OFFER, DHCP_ACK, DHCP_NAK)); > > packet = malloc0(sizeof(DHCPPacket) + req->max_optlen); > if (!packet) > return -ENOMEM; > > r = dhcp_message_init(&packet->dhcp, BOOTREPLY, > be32toh(req->message->xid), > - type, req->max_optlen, &optoffset); > + type, ARPHRD_ETHER, req->max_optlen, > &optoffset); > if (r < 0) > return r; > > packet->dhcp.flags = req->message->flags; > packet->dhcp.giaddr = req->message->giaddr; > memcpy(&packet->dhcp.chaddr, &req->message->chaddr, ETH_ALEN); > > @@ -491,16 +491,16 @@ static int server_send_forcerenew(sd_dhcp_server > *server, be32_t address, be32_t > assert(chaddr); > > packet = malloc0(sizeof(DHCPPacket) + DHCP_MIN_OPTIONS_SIZE); > if (!packet) > return -ENOMEM; > > r = dhcp_message_init(&packet->dhcp, BOOTREPLY, 0, > - DHCP_FORCERENEW, DHCP_MIN_OPTIONS_SIZE, > - &optoffset); > + DHCP_FORCERENEW, ARPHRD_ETHER, > + DHCP_MIN_OPTIONS_SIZE, &optoffset); > if (r < 0) > return r; > > r = dhcp_option_append(&packet->dhcp, DHCP_MIN_OPTIONS_SIZE, > &optoffset, 0, DHCP_OPTION_END, 0, NULL); > if (r < 0) > return r; > diff --git a/src/libsystemd-network/test-dhcp-client.c > b/src/libsystemd-network/test-dhcp-client.c > index c48aa04..7dab97d 100644 > --- a/src/libsystemd-network/test-dhcp-client.c > +++ b/src/libsystemd-network/test-dhcp-client.c > @@ -192,15 +192,17 @@ int dhcp_network_send_raw_socket(int s, const union > sockaddr_union *link, > > assert_se(callback_recv); > callback_recv(size, &discover->dhcp); > > return 575; > } > > -int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, > uint32_t id, struct ether_addr mac) > +int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, > + uint32_t id, const uint8_t *addr, > + size_t addr_len, uint16_t arp_type) > { > if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0) > return -errno; > > return test_fd[0]; > } > > @@ -240,15 +242,18 @@ static void test_discover_message(sd_event *e) > assert_se(r >= 0); > assert_se(client); > > r = sd_dhcp_client_attach_event(client, e, 0); > assert_se(r >= 0); > > assert_se(sd_dhcp_client_set_index(client, 42) >= 0); > - assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0); > + assert_se(sd_dhcp_client_set_mac(client, > + (const uint8_t *) &mac_addr, > + sizeof (mac_addr), > + ARPHRD_ETHER) >= 0); > > assert_se(sd_dhcp_client_set_request_option(client, 248) >= 0); > > callback_recv = test_discover_message_verify; > > res = sd_dhcp_client_start(client); > > @@ -458,15 +463,18 @@ static void test_addr_acq(sd_event *e) { > assert_se(r >= 0); > assert_se(client); > > r = sd_dhcp_client_attach_event(client, e, 0); > assert_se(r >= 0); > > assert_se(sd_dhcp_client_set_index(client, 42) >= 0); > - assert_se(sd_dhcp_client_set_mac(client, &mac_addr) >= 0); > + assert_se(sd_dhcp_client_set_mac(client, > + (const uint8_t *) &mac_addr, > + sizeof (mac_addr), > + ARPHRD_ETHER) >= 0); > > assert_se(sd_dhcp_client_set_callback(client, > test_addr_acq_acquired, e) > >= 0); > > callback_recv = test_addr_acq_recv_discover; > > assert_se(sd_event_add_time(e, &test_hangcheck, > diff --git a/src/libsystemd-network/test-dhcp-option.c > b/src/libsystemd-network/test-dhcp-option.c > index 92c58e0..ed81fe7 100644 > --- a/src/libsystemd-network/test-dhcp-option.c > +++ b/src/libsystemd-network/test-dhcp-option.c > @@ -88,15 +88,15 @@ static void test_message_init(void) > size_t optlen = 4, optoffset; > size_t len = sizeof(DHCPMessage) + optlen; > uint8_t *magic; > > message = malloc0(len); > > assert_se(dhcp_message_init(message, BOOTREQUEST, 0x12345678, > - DHCP_DISCOVER, optlen, &optoffset) >= 0); > + DHCP_DISCOVER, ARPHRD_ETHER, optlen, &optoffset) >= 0); > > assert_se(message->xid == htobe32(0x12345678)); > assert_se(message->op == BOOTREQUEST); > > magic = (uint8_t*)&message->magic; > > assert_se(magic[0] == 99); > diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c > index eff14ca..6516f38 100644 > --- a/src/network/networkd-link.c > +++ b/src/network/networkd-link.c > @@ -1815,15 +1815,17 @@ static int link_configure(Link *link) { > if (r < 0) > return r; > > r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); > if (r < 0) > return r; > > - r = sd_dhcp_client_set_mac(link->dhcp_client, &link->mac); > + r = sd_dhcp_client_set_mac(link->dhcp_client, > + (const uint8_t *) &link->mac, > + sizeof (link->mac), ARPHRD_ETHER); > if (r < 0) > return r; > > r = sd_dhcp_client_set_index(link->dhcp_client, > link->ifindex); > if (r < 0) > return r; > > @@ -2246,15 +2248,18 @@ int link_update(Link *link, sd_rtnl_message *m) { > "address in IPv4LL > client: %s", > strerror(-r)); > return r; > } > } > > if (link->dhcp_client) { > - r = > sd_dhcp_client_set_mac(link->dhcp_client, &link->mac); > + r = sd_dhcp_client_set_mac(link->dhcp_client, > + (const uint8_t *) > &link->mac, > + sizeof > (link->mac), > + ARPHRD_ETHER); > if (r < 0) { > log_warning_link(link, "Could not > update MAC " > "address in DHCP > client: %s", > strerror(-r)); > return r; > } > } > diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h > index 98c6782..7416f82 100644 > --- a/src/systemd/sd-dhcp-client.h > +++ b/src/systemd/sd-dhcp-client.h > @@ -45,16 +45,16 @@ int sd_dhcp_client_set_callback(sd_dhcp_client *client, > sd_dhcp_client_cb_t cb, > > > int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t > option); > int sd_dhcp_client_set_request_address(sd_dhcp_client *client, > const struct in_addr *last_address); > int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int > broadcast); > int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index); > -int sd_dhcp_client_set_mac(sd_dhcp_client *client, > - const struct ether_addr *addr); > +int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr, > + size_t addr_len, uint16_t arp_type); > int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu); > int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char > *hostname); > int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const > char *vci); > int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret); > > int sd_dhcp_client_stop(sd_dhcp_client *client); > int sd_dhcp_client_start(sd_dhcp_client *client); _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel