mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
Implement set-field for IPv6 ND fields (nd_target, nd_sll, and nd_tll).
This patch adds set-field operations for nd_target, nd_sll, and nd_tll fields, with and without masks, using Nicira extensions and OpenFlow 1.2 protocol. Signed-off-by: Randall A Sharo <randall.sharo at navy.mil> Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
committed by
Ben Pfaff
parent
ed5c51108c
commit
e60e935b1f
@@ -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.
|
||||
* Copyright (c) 2013 Simon Horman
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "odp-execute.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -181,6 +182,48 @@ set_arp(struct ofpbuf *packet, const struct ovs_key_arp *key,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
odp_set_nd(struct ofpbuf *packet, const struct ovs_key_nd *key,
|
||||
const struct ovs_key_nd *mask)
|
||||
{
|
||||
const struct ovs_nd_msg *ns = ofpbuf_l4(packet);
|
||||
const struct ovs_nd_opt *nd_opt = ofpbuf_get_nd_payload(packet);
|
||||
|
||||
if (OVS_LIKELY(ns && nd_opt)) {
|
||||
int bytes_remain = ofpbuf_l4_size(packet) - sizeof(*ns);
|
||||
ovs_be32 tgt_buf[4];
|
||||
uint8_t sll_buf[ETH_ADDR_LEN] = {0};
|
||||
uint8_t tll_buf[ETH_ADDR_LEN] = {0};
|
||||
|
||||
while (bytes_remain >= ND_OPT_LEN && nd_opt->nd_opt_len != 0) {
|
||||
if (nd_opt->nd_opt_type == ND_OPT_SOURCE_LINKADDR
|
||||
&& nd_opt->nd_opt_len == 1) {
|
||||
memcpy(sll_buf, nd_opt->nd_opt_data, ETH_ADDR_LEN);
|
||||
ether_addr_copy_masked(sll_buf, key->nd_sll, mask->nd_sll);
|
||||
|
||||
/* A packet can only contain one SLL or TLL option */
|
||||
break;
|
||||
} else if (nd_opt->nd_opt_type == ND_OPT_TARGET_LINKADDR
|
||||
&& nd_opt->nd_opt_len == 1) {
|
||||
memcpy(tll_buf, nd_opt->nd_opt_data, ETH_ADDR_LEN);
|
||||
ether_addr_copy_masked(tll_buf, key->nd_tll, mask->nd_tll);
|
||||
|
||||
/* A packet can only contain one SLL or TLL option */
|
||||
break;
|
||||
}
|
||||
|
||||
nd_opt += nd_opt->nd_opt_len;
|
||||
bytes_remain -= nd_opt->nd_opt_len * ND_OPT_LEN;
|
||||
}
|
||||
|
||||
packet_set_nd(packet,
|
||||
mask_ipv6_addr(ns->target.be32,
|
||||
key->nd_target, mask->nd_target, tgt_buf),
|
||||
sll_buf,
|
||||
tll_buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a)
|
||||
{
|
||||
@@ -259,6 +302,15 @@ odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a)
|
||||
set_arp(&packet->ofpbuf, nl_attr_get(a), NULL);
|
||||
break;
|
||||
|
||||
case OVS_KEY_ATTR_ND:
|
||||
if (OVS_LIKELY(ofpbuf_get_nd_payload(&packet->ofpbuf))) {
|
||||
const struct ovs_key_nd *nd_key
|
||||
= nl_attr_get_unspec(a, sizeof(struct ovs_key_nd));
|
||||
packet_set_nd(&packet->ofpbuf, nd_key->nd_target,
|
||||
nd_key->nd_sll, nd_key->nd_tll);
|
||||
}
|
||||
break;
|
||||
|
||||
case OVS_KEY_ATTR_DP_HASH:
|
||||
md->dp_hash = nl_attr_get_u32(a);
|
||||
dpif_packet_set_dp_hash(packet, md->dp_hash);
|
||||
@@ -275,7 +327,6 @@ odp_execute_set_action(struct dpif_packet *packet, const struct nlattr *a)
|
||||
case OVS_KEY_ATTR_VLAN:
|
||||
case OVS_KEY_ATTR_ICMP:
|
||||
case OVS_KEY_ATTR_ICMPV6:
|
||||
case OVS_KEY_ATTR_ND:
|
||||
case OVS_KEY_ATTR_TCP_FLAGS:
|
||||
case __OVS_KEY_ATTR_MAX:
|
||||
default:
|
||||
@@ -348,6 +399,11 @@ odp_execute_masked_set_action(struct dpif_packet *packet,
|
||||
get_mask(a, struct ovs_key_arp));
|
||||
break;
|
||||
|
||||
case OVS_KEY_ATTR_ND:
|
||||
odp_set_nd(&packet->ofpbuf, nl_attr_get(a),
|
||||
get_mask(a, struct ovs_key_nd));
|
||||
break;
|
||||
|
||||
case OVS_KEY_ATTR_DP_HASH:
|
||||
md->dp_hash = nl_attr_get_u32(a)
|
||||
| (dpif_packet_get_dp_hash(packet) & ~*get_mask(a, uint32_t));
|
||||
@@ -367,7 +423,6 @@ odp_execute_masked_set_action(struct dpif_packet *packet,
|
||||
case OVS_KEY_ATTR_VLAN:
|
||||
case OVS_KEY_ATTR_ICMP:
|
||||
case OVS_KEY_ATTR_ICMPV6:
|
||||
case OVS_KEY_ATTR_ND:
|
||||
case OVS_KEY_ATTR_TCP_FLAGS:
|
||||
case __OVS_KEY_ATTR_MAX:
|
||||
default:
|
||||
|
Reference in New Issue
Block a user