Until now, compose_arp() has only been able to compose ARP requests. This extends it to composing general ARP packets, in particular replies. An upcoming commit will make use of this capability.
Signed-off-by: Ben Pfaff <b...@nicira.com> --- lib/packets.c | 28 ++++++++++++++++++---------- lib/packets.h | 11 ++++++++--- ofproto/ofproto-dpif-xlate.c | 3 ++- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/lib/packets.c b/lib/packets.c index 965754f..d04fffc 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. + * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -1012,9 +1012,16 @@ packet_format_tcp_flags(struct ds *s, uint16_t tcp_flags) #define ARP_PACKET_SIZE (2 + ETH_HEADER_LEN + VLAN_HEADER_LEN + \ ARP_ETH_HEADER_LEN) +/* Clears 'b' and replaces its contents by an ARP frame with the specified + * 'arp_op', 'arp_sha', 'arp_tha', 'arp_spa', and 'arp_tpa'. The outer + * Ethernet frame is initialized with Ethernet source 'arp_sha' and destination + * 'arp_tha', except that destination ff:ff:ff:ff:ff:ff is used instead if + * 'broadcast' is true. */ void -compose_arp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN], - ovs_be32 ip_src, ovs_be32 ip_dst) +compose_arp(struct dp_packet *b, uint16_t arp_op, + const uint8_t arp_sha[ETH_ADDR_LEN], + const uint8_t arp_tha[ETH_ADDR_LEN], bool broadcast, + ovs_be32 arp_spa, ovs_be32 arp_tpa) { struct eth_header *eth; struct arp_eth_header *arp; @@ -1024,8 +1031,9 @@ compose_arp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN], dp_packet_reserve(b, 2 + VLAN_HEADER_LEN); eth = dp_packet_put_uninit(b, sizeof *eth); - memcpy(eth->eth_dst, eth_addr_broadcast, ETH_ADDR_LEN); - memcpy(eth->eth_src, eth_src, ETH_ADDR_LEN); + memcpy(eth->eth_dst, broadcast ? eth_addr_broadcast : arp_tha, + ETH_ADDR_LEN); + memcpy(eth->eth_src, arp_sha, ETH_ADDR_LEN); eth->eth_type = htons(ETH_TYPE_ARP); arp = dp_packet_put_uninit(b, sizeof *arp); @@ -1033,12 +1041,12 @@ compose_arp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN], arp->ar_pro = htons(ARP_PRO_IP); arp->ar_hln = sizeof arp->ar_sha; arp->ar_pln = sizeof arp->ar_spa; - arp->ar_op = htons(ARP_OP_REQUEST); - memcpy(arp->ar_sha, eth_src, ETH_ADDR_LEN); - memset(arp->ar_tha, 0, ETH_ADDR_LEN); + arp->ar_op = htons(arp_op); + memcpy(arp->ar_sha, arp_sha, ETH_ADDR_LEN); + memcpy(arp->ar_tha, arp_tha, ETH_ADDR_LEN); - put_16aligned_be32(&arp->ar_spa, ip_src); - put_16aligned_be32(&arp->ar_tpa, ip_dst); + put_16aligned_be32(&arp->ar_spa, arp_spa); + put_16aligned_be32(&arp->ar_tpa, arp_tpa); dp_packet_reset_offsets(b); dp_packet_set_l3(b, arp); diff --git a/lib/packets.h b/lib/packets.h index e22267e..699a953 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc. + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -77,6 +77,9 @@ bool dpid_from_string(const char *s, uint64_t *dpidp); static const uint8_t eth_addr_broadcast[ETH_ADDR_LEN] OVS_UNUSED = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +static const uint8_t eth_addr_zero[ETH_ADDR_LEN] OVS_UNUSED + = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + static const uint8_t eth_addr_stp[ETH_ADDR_LEN] OVS_UNUSED = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x00 }; @@ -811,8 +814,10 @@ void packet_set_nd(struct dp_packet *, const ovs_be32 target[4], void packet_format_tcp_flags(struct ds *, uint16_t); const char *packet_tcp_flag_to_string(uint32_t flag); -void compose_arp(struct dp_packet *b, const uint8_t eth_src[ETH_ADDR_LEN], - ovs_be32 ip_src, ovs_be32 ip_dst); +void compose_arp(struct dp_packet *, uint16_t arp_op, + const uint8_t arp_sha[ETH_ADDR_LEN], + const uint8_t arp_tha[ETH_ADDR_LEN], bool broadcast, + ovs_be32 arp_spa, ovs_be32 arp_tpa); uint32_t packet_csum_pseudoheader(const struct ip_header *); #endif /* packets.h */ diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 337d6f8..ef9312b 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -2659,7 +2659,8 @@ tnl_send_arp_request(const struct xport *out_dev, const uint8_t eth_src[ETH_ADDR struct dp_packet packet; dp_packet_init(&packet, 0); - compose_arp(&packet, eth_src, ip_src, ip_dst); + compose_arp(&packet, ARP_OP_REQUEST, + eth_src, eth_addr_zero, true, ip_src, ip_dst); xlate_flood_packet(xbridge, &packet); dp_packet_uninit(&packet); -- 2.1.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev