On Thu, 2014-10-02 at 16:39 +0200, Tom Gundersen wrote: > On Fri, Sep 26, 2014 at 10:15 PM, Dan Williams <d...@redhat.com> 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. > > Sorry for taking time with this. Overall looks good, just minor comments > inline. > > > --- > > src/libsystemd-network/dhcp-internal.h | 10 +++-- > > src/libsystemd-network/dhcp-network.c | 54 ++++++++++++++++++++----- > > src/libsystemd-network/dhcp-packet.c | 8 ++-- > > src/libsystemd-network/sd-dhcp-client.c | 66 > > +++++++++++++++++++++++-------- > > src/libsystemd-network/sd-dhcp-server.c | 8 ++-- > > src/libsystemd-network/test-dhcp-client.c | 14 +++++-- > > src/libsystemd-network/test-dhcp-option.c | 2 +- > > src/network/networkd-dhcp4.c | 4 +- > > src/network/networkd-link.c | 4 +- > > src/systemd/sd-dhcp-client.h | 4 +- > > 10 files changed, 130 insertions(+), 44 deletions(-) > > > > *** Testing appreciated.... > > > > 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..29e9993 100644 > > --- a/src/libsystemd-network/dhcp-network.c > > +++ b/src/libsystemd-network/dhcp-network.c > > @@ -18,27 +18,31 @@ > > ***/ > > > > #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" > > > > -int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, > > - uint32_t xid, struct ether_addr mac_addr) > > { > > - > > +static int _bind_raw_socket(int ifindex, union sockaddr_union *link, > > + uint32_t xid, const uint8_t *mac_addr, > > + size_t mac_addr_len, > > + const uint8_t *bcast_addr, > > + const struct ether_addr *eth_mac, > > + uint16_t arp_type, uint8_t dhcp_hlen) { > > 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 ? */ > > BPF_STMT(BPF_RET + BPF_K, 0), > > /* ignore */ > > @@ -53,29 +57,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 */ > > Won't the following be all wrong in case hlen != ETHER_ADDR_LEN? I > mean we are here hard-coding it to compare 6 bytes... Or am I missing > something?
The DHCPv4 header is the same format no matter what the LL address size, but for non-ethernet the hlen is 0 and the chaddr is zeroed. The BPF is seeded with an hlen of 0 and a valid ETH_ALEN sized buffer of all zeros. So both the hlen and chaddr comparisons comparison should succeed. Does that make sense? I might have missed something too though... Dan > If there is no way to do this nicely using BPF we can just move the > mac addr check to userspace (as we are already doing for received UDP > packets). > > Cheers, > > Tom > > > - 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 *) > > eth_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 *) eth_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,27 +107,59 @@ 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; > > + memcpy(link->ll.sll_addr, bcast_addr, mac_addr_len); > > > > r = bind(s, &link->sa, sizeof(link->ll)); > > if (r < 0) > > return -errno; > > > > r = s; > > s = -1; > > > > return r; > > } > > > > +int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, > > + uint32_t xid, const uint8_t *mac_addr, > > + size_t mac_addr_len, uint16_t arp_type) { > > + static const uint8_t eth_bcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, > > 0xFF }; > > + /* Default broadcast address for IPoIB */ > > + static const uint8_t ib_bcast[] = { > > + 0x00, 0xff, 0xff, 0xff, 0xff, 0x12, 0x40, 0x1b, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0xff, 0xff, 0xff, 0xff > > + }; > > + struct ether_addr eth_mac = { { 0, 0, 0, 0, 0, 0 } }; > > + const uint8_t *bcast_addr = NULL; > > + 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); > > + bcast_addr = eth_bcast; > > + dhcp_hlen = ETH_ALEN; > > + } else if (arp_type == ARPHRD_INFINIBAND) { > > + assert_return(mac_addr_len == INFINIBAND_ALEN, -EINVAL); > > + bcast_addr = ib_bcast; > > + } else > > + return -EINVAL; > > + > > + return _bind_raw_socket(ifindex, link, xid, mac_addr, mac_addr_len, > > + bcast_addr, ð_mac, arp_type, dhcp_hlen); > > +} > > + > > int dhcp_network_bind_udp_socket(be32_t address, uint16_t port) { > > union sockaddr_union src = { > > .in.sin_family = AF_INET, > > .in.sin_port = htobe16(port), > > .in.sin_addr.s_addr = address, > > }; > > _cleanup_close_ int 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 2f94c16..ad04f98 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); > > > > @@ -333,22 +345,25 @@ static int client_message_init(sd_dhcp_client > > *client, DHCPPacket **ret, > > DHCPREQUEST messages that client sends. The BROADCAST bit will > > provide a hint to the DHCP server and BOOTP relay agent to > > broadcast > > any messages to the client on the client's subnet. > > > > Note: some interfaces needs this to be enabled, but some > > networks > > needs this to be disabled as broadcasts are filteretd, so this > > needs to be configurable */ > > - if (client->request_broadcast) > > + if (client->request_broadcast || client->arp_type != ARPHRD_ETHER) > > 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) > > @@ -839,15 +854,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) { > > @@ -883,15 +900,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); > > @@ -1327,14 +1346,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; > > @@ -1363,21 +1385,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) { > > @@ -1451,31 +1486,28 @@ static int > > client_receive_message_raw(sd_event_source *s, int fd, > > > > len -= DHCP_IP_UDP_SIZE; > > > > return client_handle_message(client, &packet->dhcp, len); > > } > > > > int sd_dhcp_client_start(sd_dhcp_client *client) { > > - char buffer[ETHER_ADDR_TO_STRING_MAX]; > > int r; > > > > assert_return(client, -EINVAL); > > > > r = client_initialize(client); > > if (r < 0) > > 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_addr_to_string(&client->client_id.mac_addr, buffer)); > > + 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 a6d6178..24fedd2 100644 > > --- a/src/libsystemd-network/sd-dhcp-server.c > > +++ b/src/libsystemd-network/sd-dhcp-server.c > > @@ -388,16 +388,16 @@ 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); > > + be32toh(req->message->xid), 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); > > > > @@ -509,16 +509,16 @@ static int server_send_forcerenew(sd_dhcp_server > > *server, be32_t address, > > 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 63cdc7a..eac3844 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-dhcp4.c b/src/network/networkd-dhcp4.c > > index e451af8..63bfa86 100644 > > --- a/src/network/networkd-dhcp4.c > > +++ b/src/network/networkd-dhcp4.c > > @@ -595,15 +595,17 @@ int dhcp4_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; > > > > diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c > > index 427f695..0cc7231 100644 > > --- a/src/network/networkd-link.c > > +++ b/src/network/networkd-link.c > > @@ -1647,15 +1647,17 @@ int link_update(Link *link, sd_rtnl_message *m) { > > strerror(-r)); > > return r; > > } > > } > > > > if (link->dhcp_client) { > > r = > > sd_dhcp_client_set_mac(link->dhcp_client, > > - &link->mac); > > + (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); > > -- > > 1.9.3 > > > > > > _______________________________________________ > > systemd-devel mailing list > > systemd-devel@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/systemd-devel _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel