Acked-by: Alex Wang <al...@nicira.com> On Sun, Jun 14, 2015 at 12:18 PM, Ben Pfaff <b...@nicira.com> wrote:
> 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 > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev