mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
packets: Generalize compose_arp().
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 <blp@nicira.com> Acked-by: Alex Wang <alexw@nicira.com>
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user