mirror of
https://github.com/openvswitch/ovs
synced 2025-09-03 07:45:30 +00:00
odp: Use struct in6_addr for IPv6 addresses.
Code is simplified when the ODP keys use the same type as the struct flow for the IPv6 addresses. As the change is facilitated by extract-odp-netlink-h, this change only affects the userspace. We already do the same for the ethernet addresses. Signed-off-by: Jarno Rajahalme <jarno@ovn.org> Acked-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
@@ -22,10 +22,14 @@ $i\
|
|||||||
#endif\
|
#endif\
|
||||||
|
|
||||||
# Use OVS's own struct eth_addr instead of a 6-byte char array.
|
# Use OVS's own struct eth_addr instead of a 6-byte char array.
|
||||||
s,<linux/types\.h>,"openvswitch/types.h",
|
s,<linux/types\.h>,"openvswitch/types.h"\
|
||||||
|
#include <netinet/in.h>,
|
||||||
s,#.*<linux/if_ether\.h>,,
|
s,#.*<linux/if_ether\.h>,,
|
||||||
s/__u8[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*\[[[:space:]]*ETH_ALEN[[:space:]]*\]/struct eth_addr \1/
|
s/__u8[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*\[[[:space:]]*ETH_ALEN[[:space:]]*\]/struct eth_addr \1/
|
||||||
|
|
||||||
|
# Transform IPv6 addresses from an array to struct in6_addr
|
||||||
|
s/__be32[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*\[[[:space:]]*4[[:space:]]*\]/struct in6_addr \1/
|
||||||
|
|
||||||
# Transform most Linux-specific __u<N> types into C99 uint<N>_t types,
|
# Transform most Linux-specific __u<N> types into C99 uint<N>_t types,
|
||||||
# and most Linux-specific __be<N> into Open vSwitch ovs_be<N>,
|
# and most Linux-specific __be<N> into Open vSwitch ovs_be<N>,
|
||||||
# and use the appropriate userspace header.
|
# and use the appropriate userspace header.
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include "csum.h"
|
#include "csum.h"
|
||||||
#include "unaligned.h"
|
#include "unaligned.h"
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#ifndef __CHECKER__
|
#ifndef __CHECKER__
|
||||||
/* Returns the IP checksum of the 'n' bytes in 'data'.
|
/* Returns the IP checksum of the 'n' bytes in 'data'.
|
||||||
@@ -117,9 +118,15 @@ recalc_csum48(ovs_be16 old_csum, const struct eth_addr old_mac,
|
|||||||
* changed to contain 'new_u32[4]'. */
|
* changed to contain 'new_u32[4]'. */
|
||||||
ovs_be16
|
ovs_be16
|
||||||
recalc_csum128(ovs_be16 old_csum, ovs_16aligned_be32 old_u32[4],
|
recalc_csum128(ovs_be16 old_csum, ovs_16aligned_be32 old_u32[4],
|
||||||
const ovs_be32 new_u32[4])
|
const struct in6_addr *new_in6)
|
||||||
{
|
{
|
||||||
ovs_be16 new_csum = old_csum;
|
ovs_be16 new_csum = old_csum;
|
||||||
|
#ifndef s6_addr32
|
||||||
|
ovs_be32 new_u32[4];
|
||||||
|
memcpy(new_u32, new_in6, sizeof new_u32);
|
||||||
|
#else
|
||||||
|
const ovs_be32 *new_u32 = new_in6->s6_addr32;
|
||||||
|
#endif
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 4; ++i) {
|
for (i = 0; i < 4; ++i) {
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "openvswitch/types.h"
|
#include "openvswitch/types.h"
|
||||||
|
|
||||||
|
struct in6_addr;
|
||||||
|
|
||||||
ovs_be16 csum(const void *, size_t);
|
ovs_be16 csum(const void *, size_t);
|
||||||
uint32_t csum_continue(uint32_t partial, const void *, size_t);
|
uint32_t csum_continue(uint32_t partial, const void *, size_t);
|
||||||
ovs_be16 csum_finish(uint32_t partial);
|
ovs_be16 csum_finish(uint32_t partial);
|
||||||
@@ -29,7 +31,7 @@ ovs_be16 recalc_csum32(ovs_be16 old_csum, ovs_be32 old_u32, ovs_be32 new_u32);
|
|||||||
ovs_be16 recalc_csum48(ovs_be16 old_csum, const struct eth_addr old_mac,
|
ovs_be16 recalc_csum48(ovs_be16 old_csum, const struct eth_addr old_mac,
|
||||||
const struct eth_addr new_mac);
|
const struct eth_addr new_mac);
|
||||||
ovs_be16 recalc_csum128(ovs_be16 old_csum, ovs_16aligned_be32 old_u32[4],
|
ovs_be16 recalc_csum128(ovs_be16 old_csum, ovs_16aligned_be32 old_u32[4],
|
||||||
const ovs_be32 new_u32[4]);
|
const struct in6_addr *);
|
||||||
|
|
||||||
#ifndef __CHECKER__
|
#ifndef __CHECKER__
|
||||||
/* Adds the 16 bits in 'new' to the partial IP checksum 'partial' and returns
|
/* Adds the 16 bits in 'new' to the partial IP checksum 'partial' and returns
|
||||||
|
@@ -116,14 +116,21 @@ odp_set_ipv4(struct dp_packet *packet, const struct ovs_key_ipv4 *key,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ovs_be32 *
|
static struct in6_addr *
|
||||||
mask_ipv6_addr(const ovs_16aligned_be32 *old, const ovs_be32 *addr,
|
mask_ipv6_addr(const ovs_16aligned_be32 *old, const struct in6_addr *addr,
|
||||||
const ovs_be32 *mask, ovs_be32 *masked)
|
const struct in6_addr *mask, struct in6_addr *masked)
|
||||||
{
|
{
|
||||||
|
#ifdef s6_addr32
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
masked[i] = addr[i] | (get_16aligned_be32(&old[i]) & ~mask[i]);
|
masked->s6_addr32[i] = addr->s6_addr32[i]
|
||||||
|
| (get_16aligned_be32(&old[i]) & ~mask->s6_addr32[i]);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
const uint8_t *old8 = (const uint8_t *)old;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
masked->s6_addr[i] = addr->s6_addr[i] | (old8[i] & ~mask->s6_addr[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return masked;
|
return masked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,14 +139,16 @@ odp_set_ipv6(struct dp_packet *packet, const struct ovs_key_ipv6 *key,
|
|||||||
const struct ovs_key_ipv6 *mask)
|
const struct ovs_key_ipv6 *mask)
|
||||||
{
|
{
|
||||||
struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);
|
struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);
|
||||||
ovs_be32 sbuf[4], dbuf[4];
|
struct in6_addr sbuf, dbuf;
|
||||||
uint8_t old_tc = ntohl(get_16aligned_be32(&nh->ip6_flow)) >> 20;
|
uint8_t old_tc = ntohl(get_16aligned_be32(&nh->ip6_flow)) >> 20;
|
||||||
ovs_be32 old_fl = get_16aligned_be32(&nh->ip6_flow) & htonl(0xfffff);
|
ovs_be32 old_fl = get_16aligned_be32(&nh->ip6_flow) & htonl(0xfffff);
|
||||||
|
|
||||||
packet_set_ipv6(
|
packet_set_ipv6(
|
||||||
packet,
|
packet,
|
||||||
mask_ipv6_addr(nh->ip6_src.be32, key->ipv6_src, mask->ipv6_src, sbuf),
|
mask_ipv6_addr(nh->ip6_src.be32, &key->ipv6_src, &mask->ipv6_src,
|
||||||
mask_ipv6_addr(nh->ip6_dst.be32, key->ipv6_dst, mask->ipv6_dst, dbuf),
|
&sbuf),
|
||||||
|
mask_ipv6_addr(nh->ip6_dst.be32, &key->ipv6_dst, &mask->ipv6_dst,
|
||||||
|
&dbuf),
|
||||||
key->ipv6_tclass | (old_tc & ~mask->ipv6_tclass),
|
key->ipv6_tclass | (old_tc & ~mask->ipv6_tclass),
|
||||||
key->ipv6_label | (old_fl & ~mask->ipv6_label),
|
key->ipv6_label | (old_fl & ~mask->ipv6_label),
|
||||||
key->ipv6_hlimit | (nh->ip6_hlim & ~mask->ipv6_hlimit));
|
key->ipv6_hlimit | (nh->ip6_hlim & ~mask->ipv6_hlimit));
|
||||||
@@ -228,7 +237,7 @@ odp_set_nd(struct dp_packet *packet, const struct ovs_key_nd *key,
|
|||||||
|
|
||||||
if (OVS_LIKELY(ns && nd_opt)) {
|
if (OVS_LIKELY(ns && nd_opt)) {
|
||||||
int bytes_remain = dp_packet_l4_size(packet) - sizeof(*ns);
|
int bytes_remain = dp_packet_l4_size(packet) - sizeof(*ns);
|
||||||
ovs_be32 tgt_buf[4];
|
struct in6_addr tgt_buf;
|
||||||
struct eth_addr sll_buf = eth_addr_zero;
|
struct eth_addr sll_buf = eth_addr_zero;
|
||||||
struct eth_addr tll_buf = eth_addr_zero;
|
struct eth_addr tll_buf = eth_addr_zero;
|
||||||
|
|
||||||
@@ -254,8 +263,8 @@ odp_set_nd(struct dp_packet *packet, const struct ovs_key_nd *key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
packet_set_nd(packet,
|
packet_set_nd(packet,
|
||||||
mask_ipv6_addr(ns->target.be32,
|
mask_ipv6_addr(ns->target.be32, &key->nd_target,
|
||||||
key->nd_target, mask->nd_target, tgt_buf),
|
&mask->nd_target, &tgt_buf),
|
||||||
sll_buf,
|
sll_buf,
|
||||||
tll_buf);
|
tll_buf);
|
||||||
}
|
}
|
||||||
@@ -295,7 +304,7 @@ odp_execute_set_action(struct dp_packet *packet, const struct nlattr *a)
|
|||||||
|
|
||||||
case OVS_KEY_ATTR_IPV6:
|
case OVS_KEY_ATTR_IPV6:
|
||||||
ipv6_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv6));
|
ipv6_key = nl_attr_get_unspec(a, sizeof(struct ovs_key_ipv6));
|
||||||
packet_set_ipv6(packet, ipv6_key->ipv6_src, ipv6_key->ipv6_dst,
|
packet_set_ipv6(packet, &ipv6_key->ipv6_src, &ipv6_key->ipv6_dst,
|
||||||
ipv6_key->ipv6_tclass, ipv6_key->ipv6_label,
|
ipv6_key->ipv6_tclass, ipv6_key->ipv6_label,
|
||||||
ipv6_key->ipv6_hlimit);
|
ipv6_key->ipv6_hlimit);
|
||||||
break;
|
break;
|
||||||
@@ -352,7 +361,7 @@ odp_execute_set_action(struct dp_packet *packet, const struct nlattr *a)
|
|||||||
if (OVS_LIKELY(dp_packet_get_nd_payload(packet))) {
|
if (OVS_LIKELY(dp_packet_get_nd_payload(packet))) {
|
||||||
const struct ovs_key_nd *nd_key
|
const struct ovs_key_nd *nd_key
|
||||||
= nl_attr_get_unspec(a, sizeof(struct ovs_key_nd));
|
= nl_attr_get_unspec(a, sizeof(struct ovs_key_nd));
|
||||||
packet_set_nd(packet, nd_key->nd_target, nd_key->nd_sll,
|
packet_set_nd(packet, &nd_key->nd_target, nd_key->nd_sll,
|
||||||
nd_key->nd_tll);
|
nd_key->nd_tll);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -2059,8 +2059,8 @@ odp_mask_is_exact(enum ovs_key_attr attr, const void *mask, size_t size)
|
|||||||
&& ipv6_mask->ipv6_tclass == UINT8_MAX
|
&& ipv6_mask->ipv6_tclass == UINT8_MAX
|
||||||
&& ipv6_mask->ipv6_hlimit == UINT8_MAX
|
&& ipv6_mask->ipv6_hlimit == UINT8_MAX
|
||||||
&& ipv6_mask->ipv6_frag == UINT8_MAX
|
&& ipv6_mask->ipv6_frag == UINT8_MAX
|
||||||
&& ipv6_mask_is_exact((const struct in6_addr *)ipv6_mask->ipv6_src)
|
&& ipv6_mask_is_exact(&ipv6_mask->ipv6_src)
|
||||||
&& ipv6_mask_is_exact((const struct in6_addr *)ipv6_mask->ipv6_dst);
|
&& ipv6_mask_is_exact(&ipv6_mask->ipv6_dst);
|
||||||
}
|
}
|
||||||
if (attr == OVS_KEY_ATTR_TUNNEL) {
|
if (attr == OVS_KEY_ATTR_TUNNEL) {
|
||||||
return false;
|
return false;
|
||||||
@@ -2209,16 +2209,6 @@ format_in6_addr(struct ds *ds, const char *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
format_ipv6(struct ds *ds, const char *name, const ovs_be32 key_[4],
|
|
||||||
const ovs_be32 (*mask_)[4], bool verbose)
|
|
||||||
{
|
|
||||||
format_in6_addr(ds, name,
|
|
||||||
(const struct in6_addr *)key_,
|
|
||||||
mask_ ? (const struct in6_addr *)*mask_ : NULL,
|
|
||||||
verbose);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
format_ipv6_label(struct ds *ds, const char *name, ovs_be32 key,
|
format_ipv6_label(struct ds *ds, const char *name, ovs_be32 key,
|
||||||
const ovs_be32 *mask, bool verbose)
|
const ovs_be32 *mask, bool verbose)
|
||||||
@@ -2866,16 +2856,18 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
|
|||||||
const struct ovs_key_ipv6 *key = nl_attr_get(a);
|
const struct ovs_key_ipv6 *key = nl_attr_get(a);
|
||||||
const struct ovs_key_ipv6 *mask = ma ? nl_attr_get(ma) : NULL;
|
const struct ovs_key_ipv6 *mask = ma ? nl_attr_get(ma) : NULL;
|
||||||
|
|
||||||
format_ipv6(ds, "src", key->ipv6_src, MASK(mask, ipv6_src), verbose);
|
format_in6_addr(ds, "src", &key->ipv6_src, MASK(mask, ipv6_src),
|
||||||
format_ipv6(ds, "dst", key->ipv6_dst, MASK(mask, ipv6_dst), verbose);
|
verbose);
|
||||||
|
format_in6_addr(ds, "dst", &key->ipv6_dst, MASK(mask, ipv6_dst),
|
||||||
|
verbose);
|
||||||
format_ipv6_label(ds, "label", key->ipv6_label, MASK(mask, ipv6_label),
|
format_ipv6_label(ds, "label", key->ipv6_label, MASK(mask, ipv6_label),
|
||||||
verbose);
|
verbose);
|
||||||
format_u8u(ds, "proto", key->ipv6_proto, MASK(mask, ipv6_proto),
|
format_u8u(ds, "proto", key->ipv6_proto, MASK(mask, ipv6_proto),
|
||||||
verbose);
|
verbose);
|
||||||
format_u8x(ds, "tclass", key->ipv6_tclass, MASK(mask, ipv6_tclass),
|
format_u8x(ds, "tclass", key->ipv6_tclass, MASK(mask, ipv6_tclass),
|
||||||
verbose);
|
verbose);
|
||||||
format_u8u(ds, "hlimit", key->ipv6_hlimit, MASK(mask, ipv6_hlimit),
|
format_u8u(ds, "hlimit", key->ipv6_hlimit, MASK(mask, ipv6_hlimit),
|
||||||
verbose);
|
verbose);
|
||||||
format_frag(ds, "frag", key->ipv6_frag, MASK(mask, ipv6_frag),
|
format_frag(ds, "frag", key->ipv6_frag, MASK(mask, ipv6_frag),
|
||||||
verbose);
|
verbose);
|
||||||
ds_chomp(ds, ',');
|
ds_chomp(ds, ',');
|
||||||
@@ -2941,8 +2933,8 @@ format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
|
|||||||
const struct ovs_key_nd *mask = ma ? nl_attr_get(ma) : NULL;
|
const struct ovs_key_nd *mask = ma ? nl_attr_get(ma) : NULL;
|
||||||
const struct ovs_key_nd *key = nl_attr_get(a);
|
const struct ovs_key_nd *key = nl_attr_get(a);
|
||||||
|
|
||||||
format_ipv6(ds, "target", key->nd_target, MASK(mask, nd_target),
|
format_in6_addr(ds, "target", &key->nd_target, MASK(mask, nd_target),
|
||||||
verbose);
|
verbose);
|
||||||
format_eth(ds, "sll", key->nd_sll, MASK(mask, nd_sll), verbose);
|
format_eth(ds, "sll", key->nd_sll, MASK(mask, nd_sll), verbose);
|
||||||
format_eth(ds, "tll", key->nd_tll, MASK(mask, nd_tll), verbose);
|
format_eth(ds, "tll", key->nd_tll, MASK(mask, nd_tll), verbose);
|
||||||
|
|
||||||
@@ -3240,13 +3232,6 @@ scan_in6_addr(const char *s, struct in6_addr *key, struct in6_addr *mask)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
scan_ipv6(const char *s, ovs_be32 (*key)[4], ovs_be32 (*mask)[4])
|
|
||||||
{
|
|
||||||
return scan_in6_addr(s, key ? (struct in6_addr *) *key : NULL,
|
|
||||||
mask ? (struct in6_addr *) *mask : NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
scan_ipv6_label(const char *s, ovs_be32 *key, ovs_be32 *mask)
|
scan_ipv6_label(const char *s, ovs_be32 *key, ovs_be32 *mask)
|
||||||
{
|
{
|
||||||
@@ -4119,8 +4104,8 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
|
|||||||
} SCAN_END(OVS_KEY_ATTR_IPV4);
|
} SCAN_END(OVS_KEY_ATTR_IPV4);
|
||||||
|
|
||||||
SCAN_BEGIN("ipv6(", struct ovs_key_ipv6) {
|
SCAN_BEGIN("ipv6(", struct ovs_key_ipv6) {
|
||||||
SCAN_FIELD("src=", ipv6, ipv6_src);
|
SCAN_FIELD("src=", in6_addr, ipv6_src);
|
||||||
SCAN_FIELD("dst=", ipv6, ipv6_dst);
|
SCAN_FIELD("dst=", in6_addr, ipv6_dst);
|
||||||
SCAN_FIELD("label=", ipv6_label, ipv6_label);
|
SCAN_FIELD("label=", ipv6_label, ipv6_label);
|
||||||
SCAN_FIELD("proto=", u8, ipv6_proto);
|
SCAN_FIELD("proto=", u8, ipv6_proto);
|
||||||
SCAN_FIELD("tclass=", u8, ipv6_tclass);
|
SCAN_FIELD("tclass=", u8, ipv6_tclass);
|
||||||
@@ -4164,7 +4149,7 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,
|
|||||||
} SCAN_END(OVS_KEY_ATTR_ARP);
|
} SCAN_END(OVS_KEY_ATTR_ARP);
|
||||||
|
|
||||||
SCAN_BEGIN("nd(", struct ovs_key_nd) {
|
SCAN_BEGIN("nd(", struct ovs_key_nd) {
|
||||||
SCAN_FIELD("target=", ipv6, nd_target);
|
SCAN_FIELD("target=", in6_addr, nd_target);
|
||||||
SCAN_FIELD("sll=", eth, nd_sll);
|
SCAN_FIELD("sll=", eth, nd_sll);
|
||||||
SCAN_FIELD("tll=", eth, nd_tll);
|
SCAN_FIELD("tll=", eth, nd_tll);
|
||||||
} SCAN_END(OVS_KEY_ATTR_ND);
|
} SCAN_END(OVS_KEY_ATTR_ND);
|
||||||
@@ -4455,8 +4440,7 @@ odp_flow_key_from_flow__(const struct odp_flow_key_parms *parms,
|
|||||||
|
|
||||||
nd_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ND,
|
nd_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ND,
|
||||||
sizeof *nd_key);
|
sizeof *nd_key);
|
||||||
memcpy(nd_key->nd_target, &data->nd_target,
|
nd_key->nd_target = data->nd_target;
|
||||||
sizeof nd_key->nd_target);
|
|
||||||
nd_key->nd_sll = data->arp_sha;
|
nd_key->nd_sll = data->arp_sha;
|
||||||
nd_key->nd_tll = data->arp_tha;
|
nd_key->nd_tll = data->arp_tha;
|
||||||
}
|
}
|
||||||
@@ -4986,8 +4970,7 @@ parse_l2_5_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1],
|
|||||||
const struct ovs_key_nd *nd_key;
|
const struct ovs_key_nd *nd_key;
|
||||||
|
|
||||||
nd_key = nl_attr_get(attrs[OVS_KEY_ATTR_ND]);
|
nd_key = nl_attr_get(attrs[OVS_KEY_ATTR_ND]);
|
||||||
memcpy(&flow->nd_target, nd_key->nd_target,
|
flow->nd_target = nd_key->nd_target;
|
||||||
sizeof flow->nd_target);
|
|
||||||
flow->arp_sha = nd_key->nd_sll;
|
flow->arp_sha = nd_key->nd_sll;
|
||||||
flow->arp_tha = nd_key->nd_tll;
|
flow->arp_tha = nd_key->nd_tll;
|
||||||
if (is_mask) {
|
if (is_mask) {
|
||||||
@@ -5613,8 +5596,8 @@ commit_set_ipv4_action(const struct flow *flow, struct flow *base_flow,
|
|||||||
static void
|
static void
|
||||||
get_ipv6_key(const struct flow *flow, struct ovs_key_ipv6 *ipv6, bool is_mask)
|
get_ipv6_key(const struct flow *flow, struct ovs_key_ipv6 *ipv6, bool is_mask)
|
||||||
{
|
{
|
||||||
memcpy(ipv6->ipv6_src, &flow->ipv6_src, sizeof ipv6->ipv6_src);
|
ipv6->ipv6_src = flow->ipv6_src;
|
||||||
memcpy(ipv6->ipv6_dst, &flow->ipv6_dst, sizeof ipv6->ipv6_dst);
|
ipv6->ipv6_dst = flow->ipv6_dst;
|
||||||
ipv6->ipv6_label = flow->ipv6_label;
|
ipv6->ipv6_label = flow->ipv6_label;
|
||||||
ipv6->ipv6_proto = flow->nw_proto;
|
ipv6->ipv6_proto = flow->nw_proto;
|
||||||
ipv6->ipv6_tclass = flow->nw_tos;
|
ipv6->ipv6_tclass = flow->nw_tos;
|
||||||
@@ -5625,8 +5608,8 @@ get_ipv6_key(const struct flow *flow, struct ovs_key_ipv6 *ipv6, bool is_mask)
|
|||||||
static void
|
static void
|
||||||
put_ipv6_key(const struct ovs_key_ipv6 *ipv6, struct flow *flow, bool is_mask)
|
put_ipv6_key(const struct ovs_key_ipv6 *ipv6, struct flow *flow, bool is_mask)
|
||||||
{
|
{
|
||||||
memcpy(&flow->ipv6_src, ipv6->ipv6_src, sizeof flow->ipv6_src);
|
flow->ipv6_src = ipv6->ipv6_src;
|
||||||
memcpy(&flow->ipv6_dst, ipv6->ipv6_dst, sizeof flow->ipv6_dst);
|
flow->ipv6_dst = ipv6->ipv6_dst;
|
||||||
flow->ipv6_label = ipv6->ipv6_label;
|
flow->ipv6_label = ipv6->ipv6_label;
|
||||||
flow->nw_proto = ipv6->ipv6_proto;
|
flow->nw_proto = ipv6->ipv6_proto;
|
||||||
flow->nw_tos = ipv6->ipv6_tclass;
|
flow->nw_tos = ipv6->ipv6_tclass;
|
||||||
@@ -5748,7 +5731,7 @@ commit_set_icmp_action(const struct flow *flow, struct flow *base_flow,
|
|||||||
static void
|
static void
|
||||||
get_nd_key(const struct flow *flow, struct ovs_key_nd *nd)
|
get_nd_key(const struct flow *flow, struct ovs_key_nd *nd)
|
||||||
{
|
{
|
||||||
memcpy(nd->nd_target, &flow->nd_target, sizeof flow->nd_target);
|
nd->nd_target = flow->nd_target;
|
||||||
/* nd_sll and nd_tll are stored in arp_sha and arp_tha, respectively */
|
/* nd_sll and nd_tll are stored in arp_sha and arp_tha, respectively */
|
||||||
nd->nd_sll = flow->arp_sha;
|
nd->nd_sll = flow->arp_sha;
|
||||||
nd->nd_tll = flow->arp_tha;
|
nd->nd_tll = flow->arp_tha;
|
||||||
@@ -5757,7 +5740,7 @@ get_nd_key(const struct flow *flow, struct ovs_key_nd *nd)
|
|||||||
static void
|
static void
|
||||||
put_nd_key(const struct ovs_key_nd *nd, struct flow *flow)
|
put_nd_key(const struct ovs_key_nd *nd, struct flow *flow)
|
||||||
{
|
{
|
||||||
memcpy(&flow->nd_target, nd->nd_target, sizeof flow->nd_target);
|
flow->nd_target = nd->nd_target;
|
||||||
/* nd_sll and nd_tll are stored in arp_sha and arp_tha, respectively */
|
/* nd_sll and nd_tll are stored in arp_sha and arp_tha, respectively */
|
||||||
flow->arp_sha = nd->nd_sll;
|
flow->arp_sha = nd->nd_sll;
|
||||||
flow->arp_tha = nd->nd_tll;
|
flow->arp_tha = nd->nd_tll;
|
||||||
|
@@ -960,7 +960,8 @@ packet_rh_present(struct dp_packet *packet, uint8_t *nexthdr)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
packet_update_csum128(struct dp_packet *packet, uint8_t proto,
|
packet_update_csum128(struct dp_packet *packet, uint8_t proto,
|
||||||
ovs_16aligned_be32 addr[4], const ovs_be32 new_addr[4])
|
ovs_16aligned_be32 addr[4],
|
||||||
|
const struct in6_addr *new_addr)
|
||||||
{
|
{
|
||||||
size_t l4_size = dp_packet_l4_size(packet);
|
size_t l4_size = dp_packet_l4_size(packet);
|
||||||
|
|
||||||
@@ -987,7 +988,8 @@ packet_update_csum128(struct dp_packet *packet, uint8_t proto,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
packet_set_ipv6_addr(struct dp_packet *packet, uint8_t proto,
|
packet_set_ipv6_addr(struct dp_packet *packet, uint8_t proto,
|
||||||
ovs_16aligned_be32 addr[4], const ovs_be32 new_addr[4],
|
ovs_16aligned_be32 addr[4],
|
||||||
|
const struct in6_addr *new_addr,
|
||||||
bool recalculate_csum)
|
bool recalculate_csum)
|
||||||
{
|
{
|
||||||
if (recalculate_csum) {
|
if (recalculate_csum) {
|
||||||
@@ -1052,8 +1054,8 @@ packet_set_ipv4(struct dp_packet *packet, ovs_be32 src, ovs_be32 dst,
|
|||||||
* appropriate. 'packet' must contain a valid IPv6 packet with correctly
|
* appropriate. 'packet' must contain a valid IPv6 packet with correctly
|
||||||
* populated l[34] offsets. */
|
* populated l[34] offsets. */
|
||||||
void
|
void
|
||||||
packet_set_ipv6(struct dp_packet *packet, const ovs_be32 src[4],
|
packet_set_ipv6(struct dp_packet *packet, const struct in6_addr *src,
|
||||||
const ovs_be32 dst[4], uint8_t key_tc, ovs_be32 key_fl,
|
const struct in6_addr *dst, uint8_t key_tc, ovs_be32 key_fl,
|
||||||
uint8_t key_hl)
|
uint8_t key_hl)
|
||||||
{
|
{
|
||||||
struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);
|
struct ovs_16aligned_ip6_hdr *nh = dp_packet_l3(packet);
|
||||||
@@ -1158,7 +1160,7 @@ packet_set_icmp(struct dp_packet *packet, uint8_t type, uint8_t code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
packet_set_nd(struct dp_packet *packet, const ovs_be32 target[4],
|
packet_set_nd(struct dp_packet *packet, const struct in6_addr *target,
|
||||||
const struct eth_addr sll, const struct eth_addr tll)
|
const struct eth_addr sll, const struct eth_addr tll)
|
||||||
{
|
{
|
||||||
struct ovs_nd_msg *ns;
|
struct ovs_nd_msg *ns;
|
||||||
@@ -1174,9 +1176,8 @@ packet_set_nd(struct dp_packet *packet, const ovs_be32 target[4],
|
|||||||
bytes_remain -= sizeof(*ns);
|
bytes_remain -= sizeof(*ns);
|
||||||
|
|
||||||
if (memcmp(&ns->target, target, sizeof(ovs_be32[4]))) {
|
if (memcmp(&ns->target, target, sizeof(ovs_be32[4]))) {
|
||||||
packet_set_ipv6_addr(packet, IPPROTO_ICMPV6,
|
packet_set_ipv6_addr(packet, IPPROTO_ICMPV6, ns->target.be32, target,
|
||||||
ns->target.be32,
|
true);
|
||||||
target, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bytes_remain >= ND_OPT_LEN && nd_opt->nd_opt_len != 0) {
|
while (bytes_remain >= ND_OPT_LEN && nd_opt->nd_opt_len != 0) {
|
||||||
@@ -1352,19 +1353,13 @@ compose_ipv6(struct dp_packet *packet, uint8_t proto,
|
|||||||
struct ip6_hdr *nh;
|
struct ip6_hdr *nh;
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
/* Copy 'src' and 'dst' to temporary buffers to prevent misaligned
|
|
||||||
* accesses. */
|
|
||||||
ovs_be32 sbuf[4], dbuf[4];
|
|
||||||
memcpy(sbuf, src, sizeof sbuf);
|
|
||||||
memcpy(dbuf, dst, sizeof dbuf);
|
|
||||||
|
|
||||||
nh = dp_packet_l3(packet);
|
nh = dp_packet_l3(packet);
|
||||||
nh->ip6_vfc = 0x60;
|
nh->ip6_vfc = 0x60;
|
||||||
nh->ip6_nxt = proto;
|
nh->ip6_nxt = proto;
|
||||||
nh->ip6_plen = htons(size);
|
nh->ip6_plen = htons(size);
|
||||||
data = dp_packet_put_zeros(packet, size);
|
data = dp_packet_put_zeros(packet, size);
|
||||||
dp_packet_set_l4(packet, data);
|
dp_packet_set_l4(packet, data);
|
||||||
packet_set_ipv6(packet, sbuf, dbuf, key_tc, key_fl, key_hl);
|
packet_set_ipv6(packet, src, dst, key_tc, key_fl, key_hl);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1394,10 +1389,7 @@ compose_nd_ns(struct dp_packet *b, const struct eth_addr eth_src,
|
|||||||
nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
|
nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
|
||||||
nd_opt->nd_opt_len = 1;
|
nd_opt->nd_opt_len = 1;
|
||||||
|
|
||||||
/* Copy target address to temp buffer to prevent misaligned access. */
|
packet_set_nd(b, ipv6_dst, eth_src, eth_addr_zero);
|
||||||
ovs_be32 tbuf[4];
|
|
||||||
memcpy(tbuf, ipv6_dst->s6_addr, sizeof tbuf);
|
|
||||||
packet_set_nd(b, tbuf, eth_src, eth_addr_zero);
|
|
||||||
|
|
||||||
ns->icmph.icmp6_cksum = 0;
|
ns->icmph.icmp6_cksum = 0;
|
||||||
icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b));
|
icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b));
|
||||||
@@ -1428,10 +1420,7 @@ compose_nd_na(struct dp_packet *b,
|
|||||||
nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
|
nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
|
||||||
nd_opt->nd_opt_len = 1;
|
nd_opt->nd_opt_len = 1;
|
||||||
|
|
||||||
/* Copy target address to temp buffer to prevent misaligned access. */
|
packet_set_nd(b, ipv6_src, eth_addr_zero, eth_src);
|
||||||
ovs_be32 tbuf[4];
|
|
||||||
memcpy(tbuf, ipv6_src->s6_addr, sizeof tbuf);
|
|
||||||
packet_set_nd(b, tbuf, eth_addr_zero, eth_src);
|
|
||||||
|
|
||||||
na->icmph.icmp6_cksum = 0;
|
na->icmph.icmp6_cksum = 0;
|
||||||
icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b));
|
icmp_csum = packet_csum_pseudoheader6(dp_packet_l3(b));
|
||||||
|
@@ -1097,14 +1097,14 @@ void packet_set_ipv4(struct dp_packet *, ovs_be32 src, ovs_be32 dst, uint8_t tos
|
|||||||
uint8_t ttl);
|
uint8_t ttl);
|
||||||
void packet_set_ipv4_addr(struct dp_packet *packet, ovs_16aligned_be32 *addr,
|
void packet_set_ipv4_addr(struct dp_packet *packet, ovs_16aligned_be32 *addr,
|
||||||
ovs_be32 new_addr);
|
ovs_be32 new_addr);
|
||||||
void packet_set_ipv6(struct dp_packet *, const ovs_be32 src[4],
|
void packet_set_ipv6(struct dp_packet *, const struct in6_addr *src,
|
||||||
const ovs_be32 dst[4], uint8_t tc,
|
const struct in6_addr *dst, uint8_t tc,
|
||||||
ovs_be32 fl, uint8_t hlmit);
|
ovs_be32 fl, uint8_t hlmit);
|
||||||
void packet_set_tcp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst);
|
void packet_set_tcp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst);
|
||||||
void packet_set_udp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst);
|
void packet_set_udp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst);
|
||||||
void packet_set_sctp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst);
|
void packet_set_sctp_port(struct dp_packet *, ovs_be16 src, ovs_be16 dst);
|
||||||
void packet_set_icmp(struct dp_packet *, uint8_t type, uint8_t code);
|
void packet_set_icmp(struct dp_packet *, uint8_t type, uint8_t code);
|
||||||
void packet_set_nd(struct dp_packet *, const ovs_be32 target[4],
|
void packet_set_nd(struct dp_packet *, const struct in6_addr *target,
|
||||||
const struct eth_addr sll, const struct eth_addr tll);
|
const struct eth_addr sll, const struct eth_addr tll);
|
||||||
|
|
||||||
void packet_format_tcp_flags(struct ds *, uint16_t);
|
void packet_format_tcp_flags(struct ds *, uint16_t);
|
||||||
|
Reference in New Issue
Block a user