mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 06:45:17 +00:00
nicira-ext: Support matching ARP source and target hardware addresses.
OpenFlow 1.0 doesn't allow matching on the ARP source and target hardware address. This has caused us to introduce hacks such as the Drop Spoofed ARP action. Now that we have extensible match, we can match on more fields within ARP: - Source Hardware Address (arp_sha) - Target Hardware Address (arp_tha) Signed-off-by: Justin Pettit <jpettit@nicira.com> Acked-by: Jesse Gross <jesse@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -390,6 +390,8 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
|
|||||||
|| key->nw_proto == ARPOP_REPLY) {
|
|| key->nw_proto == ARPOP_REPLY) {
|
||||||
memcpy(&key->nw_src, arp->ar_sip, sizeof(key->nw_src));
|
memcpy(&key->nw_src, arp->ar_sip, sizeof(key->nw_src));
|
||||||
memcpy(&key->nw_dst, arp->ar_tip, sizeof(key->nw_dst));
|
memcpy(&key->nw_dst, arp->ar_tip, sizeof(key->nw_dst));
|
||||||
|
memcpy(key->arp_sha, arp->ar_sha, ETH_ALEN);
|
||||||
|
memcpy(key->arp_tha, arp->ar_tha, ETH_ALEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -538,6 +540,8 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, const struct nlattr *attr)
|
|||||||
if (arp_key->arp_op & htons(0xff00))
|
if (arp_key->arp_op & htons(0xff00))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
swkey->nw_proto = ntohs(arp_key->arp_op);
|
swkey->nw_proto = ntohs(arp_key->arp_op);
|
||||||
|
memcpy(swkey->arp_sha, arp_key->arp_sha, ETH_ALEN);
|
||||||
|
memcpy(swkey->arp_tha, arp_key->arp_tha, ETH_ALEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -665,6 +669,8 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
|
|||||||
arp_key->arp_sip = swkey->nw_src;
|
arp_key->arp_sip = swkey->nw_src;
|
||||||
arp_key->arp_tip = swkey->nw_dst;
|
arp_key->arp_tip = swkey->nw_dst;
|
||||||
arp_key->arp_op = htons(swkey->nw_proto);
|
arp_key->arp_op = htons(swkey->nw_proto);
|
||||||
|
memcpy(arp_key->arp_sha, swkey->arp_sha, ETH_ALEN);
|
||||||
|
memcpy(arp_key->arp_tha, swkey->arp_tha, ETH_ALEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -42,6 +42,8 @@ struct sw_flow_key {
|
|||||||
u8 dl_dst[ETH_ALEN]; /* Ethernet destination address. */
|
u8 dl_dst[ETH_ALEN]; /* Ethernet destination address. */
|
||||||
u8 nw_proto; /* IP protocol or lower 8 bits of ARP opcode. */
|
u8 nw_proto; /* IP protocol or lower 8 bits of ARP opcode. */
|
||||||
u8 nw_tos; /* IP ToS (DSCP field, 6 bits). */
|
u8 nw_tos; /* IP ToS (DSCP field, 6 bits). */
|
||||||
|
u8 arp_sha[ETH_ALEN]; /* ARP source hardware address. */
|
||||||
|
u8 arp_tha[ETH_ALEN]; /* ARP target hardware address. */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sw_flow {
|
struct sw_flow {
|
||||||
|
@@ -312,9 +312,9 @@ OFP_ASSERT(sizeof(struct nx_action_set_tunnel64) == 24);
|
|||||||
* Ethernet+IPv4 ARP packet for which the source Ethernet address inside the
|
* Ethernet+IPv4 ARP packet for which the source Ethernet address inside the
|
||||||
* ARP packet differs from the source Ethernet address in the Ethernet header.
|
* ARP packet differs from the source Ethernet address in the Ethernet header.
|
||||||
*
|
*
|
||||||
* This is useful because OpenFlow does not provide a way to match on the
|
* (This action is deprecated in favor of defining flows using the
|
||||||
* Ethernet addresses inside ARP packets, so there is no other way to drop
|
* NXM_NX_ARP_SHA flow match and will likely be removed in a future version
|
||||||
* spoofed ARPs other than sending every ARP packet to a controller. */
|
* of Open vSwitch.) */
|
||||||
struct nx_action_drop_spoofed_arp {
|
struct nx_action_drop_spoofed_arp {
|
||||||
ovs_be16 type; /* OFPAT_VENDOR. */
|
ovs_be16 type; /* OFPAT_VENDOR. */
|
||||||
ovs_be16 len; /* Length is 16. */
|
ovs_be16 len; /* Length is 16. */
|
||||||
@@ -386,6 +386,8 @@ OFP_ASSERT(sizeof(struct nx_action_pop_queue) == 16);
|
|||||||
* - NXM_OF_ARP_SPA
|
* - NXM_OF_ARP_SPA
|
||||||
* - NXM_OF_ARP_TPA
|
* - NXM_OF_ARP_TPA
|
||||||
* - NXM_NX_TUN_ID
|
* - NXM_NX_TUN_ID
|
||||||
|
* - NXM_NX_ARP_SHA
|
||||||
|
* - NXM_NX_ARP_THA
|
||||||
* - NXM_NX_REG(idx) for idx in the switch's accepted range.
|
* - NXM_NX_REG(idx) for idx in the switch's accepted range.
|
||||||
*
|
*
|
||||||
* The following nxm_header values are potentially acceptable as 'dst':
|
* The following nxm_header values are potentially acceptable as 'dst':
|
||||||
@@ -1038,6 +1040,17 @@ enum nx_mp_algorithm {
|
|||||||
#define NXM_NX_TUN_ID NXM_HEADER (0x0001, 16, 8)
|
#define NXM_NX_TUN_ID NXM_HEADER (0x0001, 16, 8)
|
||||||
#define NXM_NX_TUN_ID_W NXM_HEADER_W(0x0001, 16, 8)
|
#define NXM_NX_TUN_ID_W NXM_HEADER_W(0x0001, 16, 8)
|
||||||
|
|
||||||
|
/* For an Ethernet+IP ARP packet, the source or target hardware address
|
||||||
|
* in the ARP header. Always 0 otherwise.
|
||||||
|
*
|
||||||
|
* Prereqs: NXM_OF_ETH_TYPE must match 0x0806 exactly.
|
||||||
|
*
|
||||||
|
* Format: 48-bit Ethernet MAC address.
|
||||||
|
*
|
||||||
|
* Masking: Not maskable. */
|
||||||
|
#define NXM_NX_ARP_SHA NXM_HEADER (0x0001, 17, 6)
|
||||||
|
#define NXM_NX_ARP_THA NXM_HEADER (0x0001, 18, 6)
|
||||||
|
|
||||||
/* ## --------------------- ## */
|
/* ## --------------------- ## */
|
||||||
/* ## Requests and replies. ## */
|
/* ## Requests and replies. ## */
|
||||||
/* ## --------------------- ## */
|
/* ## --------------------- ## */
|
||||||
|
@@ -356,6 +356,8 @@ struct odp_key_arp {
|
|||||||
ovs_be32 arp_sip;
|
ovs_be32 arp_sip;
|
||||||
ovs_be32 arp_tip;
|
ovs_be32 arp_tip;
|
||||||
ovs_be16 arp_op;
|
ovs_be16 arp_op;
|
||||||
|
uint8_t arp_sha[6];
|
||||||
|
uint8_t arp_tha[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -319,6 +319,20 @@ cls_rule_set_icmp_code(struct cls_rule *rule, uint8_t icmp_code)
|
|||||||
rule->flow.icmp_code = htons(icmp_code);
|
rule->flow.icmp_code = htons(icmp_code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cls_rule_set_arp_sha(struct cls_rule *rule, const uint8_t sha[ETH_ADDR_LEN])
|
||||||
|
{
|
||||||
|
rule->wc.wildcards &= ~FWW_ARP_SHA;
|
||||||
|
memcpy(rule->flow.arp_sha, sha, ETH_ADDR_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cls_rule_set_arp_tha(struct cls_rule *rule, const uint8_t tha[ETH_ADDR_LEN])
|
||||||
|
{
|
||||||
|
rule->wc.wildcards &= ~FWW_ARP_THA;
|
||||||
|
memcpy(rule->flow.arp_tha, tha, ETH_ADDR_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns true if 'a' and 'b' have the same priority, wildcard the same
|
/* Returns true if 'a' and 'b' have the same priority, wildcard the same
|
||||||
* fields, and have the same values for fixed fields, otherwise false. */
|
* fields, and have the same values for fixed fields, otherwise false. */
|
||||||
bool
|
bool
|
||||||
@@ -467,6 +481,16 @@ cls_rule_format(const struct cls_rule *rule, struct ds *s)
|
|||||||
ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto);
|
ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (f->dl_type == htons(ETH_TYPE_ARP)) {
|
||||||
|
if (!(w & FWW_ARP_SHA)) {
|
||||||
|
ds_put_format(s, "arp_sha="ETH_ADDR_FMT",",
|
||||||
|
ETH_ADDR_ARGS(f->arp_sha));
|
||||||
|
}
|
||||||
|
if (!(w & FWW_ARP_THA)) {
|
||||||
|
ds_put_format(s, "arp_tha="ETH_ADDR_FMT",",
|
||||||
|
ETH_ADDR_ARGS(f->arp_tha));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!(w & FWW_NW_TOS)) {
|
if (!(w & FWW_NW_TOS)) {
|
||||||
ds_put_format(s, "nw_tos=%"PRIu8",", f->nw_tos);
|
ds_put_format(s, "nw_tos=%"PRIu8",", f->nw_tos);
|
||||||
}
|
}
|
||||||
@@ -947,7 +971,7 @@ flow_equal_except(const struct flow *a, const struct flow *b,
|
|||||||
const flow_wildcards_t wc = wildcards->wildcards;
|
const flow_wildcards_t wc = wildcards->wildcards;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 40 + FLOW_N_REGS * 4);
|
BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 52 + FLOW_N_REGS * 4);
|
||||||
|
|
||||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||||
if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
|
if ((a->regs[i] ^ b->regs[i]) & wildcards->reg_masks[i]) {
|
||||||
@@ -974,7 +998,9 @@ flow_equal_except(const struct flow *a, const struct flow *b,
|
|||||||
&& (wc & FWW_ETH_MCAST
|
&& (wc & FWW_ETH_MCAST
|
||||||
|| !((a->dl_dst[0] ^ b->dl_dst[0]) & 0x01))
|
|| !((a->dl_dst[0] ^ b->dl_dst[0]) & 0x01))
|
||||||
&& (wc & FWW_NW_PROTO || a->nw_proto == b->nw_proto)
|
&& (wc & FWW_NW_PROTO || a->nw_proto == b->nw_proto)
|
||||||
&& (wc & FWW_NW_TOS || a->nw_tos == b->nw_tos));
|
&& (wc & FWW_NW_TOS || a->nw_tos == b->nw_tos)
|
||||||
|
&& (wc & FWW_ARP_SHA || eth_addr_equals(a->arp_sha, b->arp_sha))
|
||||||
|
&& (wc & FWW_ARP_THA || eth_addr_equals(a->arp_tha, b->arp_tha)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -983,7 +1009,7 @@ zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
|
|||||||
const flow_wildcards_t wc = wildcards->wildcards;
|
const flow_wildcards_t wc = wildcards->wildcards;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 40 + 4 * FLOW_N_REGS);
|
BUILD_ASSERT_DECL(FLOW_SIG_SIZE == 52 + 4 * FLOW_N_REGS);
|
||||||
|
|
||||||
for (i = 0; i < FLOW_N_REGS; i++) {
|
for (i = 0; i < FLOW_N_REGS; i++) {
|
||||||
flow->regs[i] &= wildcards->reg_masks[i];
|
flow->regs[i] &= wildcards->reg_masks[i];
|
||||||
@@ -1020,4 +1046,10 @@ zero_wildcards(struct flow *flow, const struct flow_wildcards *wildcards)
|
|||||||
if (wc & FWW_NW_TOS) {
|
if (wc & FWW_NW_TOS) {
|
||||||
flow->nw_tos = 0;
|
flow->nw_tos = 0;
|
||||||
}
|
}
|
||||||
|
if (wc & FWW_ARP_SHA) {
|
||||||
|
memset(flow->arp_sha, 0, sizeof flow->arp_sha);
|
||||||
|
}
|
||||||
|
if (wc & FWW_ARP_THA) {
|
||||||
|
memset(flow->arp_tha, 0, sizeof flow->arp_tha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -101,6 +101,8 @@ bool cls_rule_set_nw_dst_masked(struct cls_rule *, ovs_be32 ip, ovs_be32 mask);
|
|||||||
void cls_rule_set_nw_tos(struct cls_rule *, uint8_t);
|
void cls_rule_set_nw_tos(struct cls_rule *, uint8_t);
|
||||||
void cls_rule_set_icmp_type(struct cls_rule *, uint8_t);
|
void cls_rule_set_icmp_type(struct cls_rule *, uint8_t);
|
||||||
void cls_rule_set_icmp_code(struct cls_rule *, uint8_t);
|
void cls_rule_set_icmp_code(struct cls_rule *, uint8_t);
|
||||||
|
void cls_rule_set_arp_sha(struct cls_rule *, const uint8_t[6]);
|
||||||
|
void cls_rule_set_arp_tha(struct cls_rule *, const uint8_t[6]);
|
||||||
|
|
||||||
bool cls_rule_equal(const struct cls_rule *, const struct cls_rule *);
|
bool cls_rule_equal(const struct cls_rule *, const struct cls_rule *);
|
||||||
|
|
||||||
|
18
lib/flow.c
18
lib/flow.c
@@ -224,6 +224,8 @@ flow_extract(struct ofpbuf *packet, ovs_be64 tun_id, uint16_t in_port,
|
|||||||
|| (flow->nw_proto == ARP_OP_REPLY)) {
|
|| (flow->nw_proto == ARP_OP_REPLY)) {
|
||||||
flow->nw_src = arp->ar_spa;
|
flow->nw_src = arp->ar_spa;
|
||||||
flow->nw_dst = arp->ar_tpa;
|
flow->nw_dst = arp->ar_tpa;
|
||||||
|
memcpy(flow->arp_sha, arp->ar_sha, ETH_ADDR_LEN);
|
||||||
|
memcpy(flow->arp_tha, arp->ar_tha, ETH_ADDR_LEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,17 +276,23 @@ flow_format(struct ds *ds, const struct flow *flow)
|
|||||||
" type%04"PRIx16
|
" type%04"PRIx16
|
||||||
" proto%"PRIu8
|
" proto%"PRIu8
|
||||||
" tos%"PRIu8
|
" tos%"PRIu8
|
||||||
" ip"IP_FMT"->"IP_FMT
|
" ip"IP_FMT"->"IP_FMT,
|
||||||
" port%"PRIu16"->%"PRIu16,
|
|
||||||
ETH_ADDR_ARGS(flow->dl_src),
|
ETH_ADDR_ARGS(flow->dl_src),
|
||||||
ETH_ADDR_ARGS(flow->dl_dst),
|
ETH_ADDR_ARGS(flow->dl_dst),
|
||||||
ntohs(flow->dl_type),
|
ntohs(flow->dl_type),
|
||||||
flow->nw_proto,
|
flow->nw_proto,
|
||||||
flow->nw_tos,
|
flow->nw_tos,
|
||||||
IP_ARGS(&flow->nw_src),
|
IP_ARGS(&flow->nw_src),
|
||||||
IP_ARGS(&flow->nw_dst),
|
IP_ARGS(&flow->nw_dst));
|
||||||
ntohs(flow->tp_src),
|
if (flow->tp_src || flow->tp_dst) {
|
||||||
ntohs(flow->tp_dst));
|
ds_put_format(ds, " port%"PRIu16"->%"PRIu16,
|
||||||
|
ntohs(flow->tp_src), ntohs(flow->tp_dst));
|
||||||
|
}
|
||||||
|
if (!eth_addr_is_zero(flow->arp_sha) || !eth_addr_is_zero(flow->arp_tha)) {
|
||||||
|
ds_put_format(ds, " arp_ha"ETH_ADDR_FMT"->"ETH_ADDR_FMT,
|
||||||
|
ETH_ADDR_ARGS(flow->arp_sha),
|
||||||
|
ETH_ADDR_ARGS(flow->arp_tha));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
15
lib/flow.h
15
lib/flow.h
@@ -54,14 +54,17 @@ struct flow {
|
|||||||
uint8_t dl_dst[6]; /* Ethernet destination address. */
|
uint8_t dl_dst[6]; /* Ethernet destination address. */
|
||||||
uint8_t nw_proto; /* IP protocol or low 8 bits of ARP opcode. */
|
uint8_t nw_proto; /* IP protocol or low 8 bits of ARP opcode. */
|
||||||
uint8_t nw_tos; /* IP ToS (DSCP field, 6 bits). */
|
uint8_t nw_tos; /* IP ToS (DSCP field, 6 bits). */
|
||||||
|
uint8_t arp_sha[6]; /* ARP source hardware address. */
|
||||||
|
uint8_t arp_tha[6]; /* ARP target hardware address. */
|
||||||
|
uint32_t reserved; /* Reserved for 64-bit packing. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Assert that there are FLOW_SIG_SIZE bytes of significant data in "struct
|
/* Assert that there are FLOW_SIG_SIZE bytes of significant data in "struct
|
||||||
* flow", followed by FLOW_PAD_SIZE bytes of padding. */
|
* flow", followed by FLOW_PAD_SIZE bytes of padding. */
|
||||||
#define FLOW_SIG_SIZE (40 + FLOW_N_REGS * 4)
|
#define FLOW_SIG_SIZE (52 + FLOW_N_REGS * 4)
|
||||||
#define FLOW_PAD_SIZE 0
|
#define FLOW_PAD_SIZE 4
|
||||||
BUILD_ASSERT_DECL(offsetof(struct flow, nw_tos) == FLOW_SIG_SIZE - 1);
|
BUILD_ASSERT_DECL(offsetof(struct flow, arp_tha) == FLOW_SIG_SIZE - 6);
|
||||||
BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->nw_tos) == 1);
|
BUILD_ASSERT_DECL(sizeof(((struct flow *)0)->arp_tha) == 6);
|
||||||
BUILD_ASSERT_DECL(sizeof(struct flow) == FLOW_SIG_SIZE + FLOW_PAD_SIZE);
|
BUILD_ASSERT_DECL(sizeof(struct flow) == FLOW_SIG_SIZE + FLOW_PAD_SIZE);
|
||||||
|
|
||||||
int flow_extract(struct ofpbuf *, uint64_t tun_id, uint16_t in_port,
|
int flow_extract(struct ofpbuf *, uint64_t tun_id, uint16_t in_port,
|
||||||
@@ -115,7 +118,9 @@ typedef unsigned int OVS_BITWISE flow_wildcards_t;
|
|||||||
/* No corresponding OFPFW_* or OVSFW_* bits. */
|
/* No corresponding OFPFW_* or OVSFW_* bits. */
|
||||||
#define FWW_ETH_MCAST ((OVS_FORCE flow_wildcards_t) (1 << 8))
|
#define FWW_ETH_MCAST ((OVS_FORCE flow_wildcards_t) (1 << 8))
|
||||||
/* multicast bit only */
|
/* multicast bit only */
|
||||||
#define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 9)) - 1))
|
#define FWW_ARP_SHA ((OVS_FORCE flow_wildcards_t) (1 << 9))
|
||||||
|
#define FWW_ARP_THA ((OVS_FORCE flow_wildcards_t) (1 << 10))
|
||||||
|
#define FWW_ALL ((OVS_FORCE flow_wildcards_t) (((1 << 11)) - 1))
|
||||||
|
|
||||||
/* Information on wildcards for a flow, as a supplement to "struct flow".
|
/* Information on wildcards for a flow, as a supplement to "struct flow".
|
||||||
*
|
*
|
||||||
|
@@ -318,6 +318,13 @@ parse_nxm_entry(struct cls_rule *rule, const struct nxm_field *f,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case NFI_NXM_NX_ARP_SHA:
|
||||||
|
memcpy(flow->arp_sha, value, ETH_ADDR_LEN);
|
||||||
|
return 0;
|
||||||
|
case NFI_NXM_NX_ARP_THA:
|
||||||
|
memcpy(flow->arp_tha, value, ETH_ADDR_LEN);
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Tunnel ID. */
|
/* Tunnel ID. */
|
||||||
case NFI_NXM_NX_TUN_ID:
|
case NFI_NXM_NX_TUN_ID:
|
||||||
if (wc->tun_id_mask) {
|
if (wc->tun_id_mask) {
|
||||||
@@ -693,6 +700,12 @@ nx_put_match(struct ofpbuf *b, const struct cls_rule *cr)
|
|||||||
}
|
}
|
||||||
nxm_put_32m(b, NXM_OF_ARP_SPA, flow->nw_src, cr->wc.nw_src_mask);
|
nxm_put_32m(b, NXM_OF_ARP_SPA, flow->nw_src, cr->wc.nw_src_mask);
|
||||||
nxm_put_32m(b, NXM_OF_ARP_TPA, flow->nw_dst, cr->wc.nw_dst_mask);
|
nxm_put_32m(b, NXM_OF_ARP_TPA, flow->nw_dst, cr->wc.nw_dst_mask);
|
||||||
|
if (!(wc & FWW_ARP_SHA)) {
|
||||||
|
nxm_put_eth(b, NXM_NX_ARP_SHA, flow->arp_sha);
|
||||||
|
}
|
||||||
|
if (!(wc & FWW_ARP_THA)) {
|
||||||
|
nxm_put_eth(b, NXM_NX_ARP_THA, flow->arp_tha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tunnel ID. */
|
/* Tunnel ID. */
|
||||||
@@ -1162,6 +1175,12 @@ nxm_read_field(const struct nxm_field *src, const struct flow *flow)
|
|||||||
#error
|
#error
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case NFI_NXM_NX_ARP_SHA:
|
||||||
|
return eth_addr_to_uint64(flow->arp_sha);
|
||||||
|
|
||||||
|
case NFI_NXM_NX_ARP_THA:
|
||||||
|
return eth_addr_to_uint64(flow->arp_tha);
|
||||||
|
|
||||||
case NFI_NXM_NX_TUN_ID_W:
|
case NFI_NXM_NX_TUN_ID_W:
|
||||||
case NFI_NXM_OF_ETH_DST_W:
|
case NFI_NXM_OF_ETH_DST_W:
|
||||||
case NFI_NXM_OF_VLAN_TCI_W:
|
case NFI_NXM_OF_VLAN_TCI_W:
|
||||||
@@ -1234,6 +1253,8 @@ nxm_write_field(const struct nxm_field *dst, struct flow *flow,
|
|||||||
case NFI_NXM_OF_IP_DST_W:
|
case NFI_NXM_OF_IP_DST_W:
|
||||||
case NFI_NXM_OF_ARP_SPA_W:
|
case NFI_NXM_OF_ARP_SPA_W:
|
||||||
case NFI_NXM_OF_ARP_TPA_W:
|
case NFI_NXM_OF_ARP_TPA_W:
|
||||||
|
case NFI_NXM_NX_ARP_SHA:
|
||||||
|
case NFI_NXM_NX_ARP_THA:
|
||||||
case N_NXM_FIELDS:
|
case N_NXM_FIELDS:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@@ -39,6 +39,8 @@ DEFINE_FIELD (OF_ARP_OP, FWW_NW_PROTO, ETH_TYPE_ARP, 0, false)
|
|||||||
DEFINE_FIELD_M(OF_ARP_SPA, 0, ETH_TYPE_ARP, 0, false)
|
DEFINE_FIELD_M(OF_ARP_SPA, 0, ETH_TYPE_ARP, 0, false)
|
||||||
DEFINE_FIELD_M(OF_ARP_TPA, 0, ETH_TYPE_ARP, 0, false)
|
DEFINE_FIELD_M(OF_ARP_TPA, 0, ETH_TYPE_ARP, 0, false)
|
||||||
DEFINE_FIELD_M(NX_TUN_ID, 0, 0, 0, true)
|
DEFINE_FIELD_M(NX_TUN_ID, 0, 0, 0, true)
|
||||||
|
DEFINE_FIELD (NX_ARP_SHA, FWW_ARP_SHA, ETH_TYPE_ARP, 0, false)
|
||||||
|
DEFINE_FIELD (NX_ARP_THA, FWW_ARP_THA, ETH_TYPE_ARP, 0, false)
|
||||||
|
|
||||||
DEFINE_FIELD_M(NX_REG0, 0, 0, 0, true)
|
DEFINE_FIELD_M(NX_REG0, 0, 0, 0, true)
|
||||||
#if FLOW_N_REGS >= 2
|
#if FLOW_N_REGS >= 2
|
||||||
|
@@ -307,9 +307,11 @@ format_odp_key_attr(const struct nlattr *a, struct ds *ds)
|
|||||||
|
|
||||||
case ODP_KEY_ATTR_ARP:
|
case ODP_KEY_ATTR_ARP:
|
||||||
arp_key = nl_attr_get(a);
|
arp_key = nl_attr_get(a);
|
||||||
ds_put_format(ds, "arp(sip="IP_FMT",tip="IP_FMT",op=%"PRIu16")",
|
ds_put_format(ds, "arp(sip="IP_FMT",tip="IP_FMT",op=%"PRIu16","
|
||||||
|
"sha="ETH_ADDR_FMT",tha="ETH_ADDR_FMT")",
|
||||||
IP_ARGS(&arp_key->arp_sip), IP_ARGS(&arp_key->arp_tip),
|
IP_ARGS(&arp_key->arp_sip), IP_ARGS(&arp_key->arp_tip),
|
||||||
ntohs(arp_key->arp_op));
|
ntohs(arp_key->arp_op), ETH_ADDR_ARGS(arp_key->arp_sha),
|
||||||
|
ETH_ADDR_ARGS(arp_key->arp_tha));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -416,6 +418,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow)
|
|||||||
arp_key->arp_sip = flow->nw_src;
|
arp_key->arp_sip = flow->nw_src;
|
||||||
arp_key->arp_tip = flow->nw_dst;
|
arp_key->arp_tip = flow->nw_dst;
|
||||||
arp_key->arp_op = htons(flow->nw_proto);
|
arp_key->arp_op = htons(flow->nw_proto);
|
||||||
|
memcpy(arp_key->arp_sha, flow->arp_sha, ETH_ADDR_LEN);
|
||||||
|
memcpy(arp_key->arp_tha, flow->arp_tha, ETH_ADDR_LEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,6 +545,8 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
flow->nw_proto = ntohs(arp_key->arp_op);
|
flow->nw_proto = ntohs(arp_key->arp_op);
|
||||||
|
memcpy(flow->arp_sha, arp_key->arp_sha, ETH_ADDR_LEN);
|
||||||
|
memcpy(flow->arp_tha, arp_key->arp_tha, ETH_ADDR_LEN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@@ -491,7 +491,9 @@ parse_protocol(const char *name, const struct protocol **p_out)
|
|||||||
FIELD(F_TP_SRC, "tp_src", FWW_TP_SRC) \
|
FIELD(F_TP_SRC, "tp_src", FWW_TP_SRC) \
|
||||||
FIELD(F_TP_DST, "tp_dst", FWW_TP_DST) \
|
FIELD(F_TP_DST, "tp_dst", FWW_TP_DST) \
|
||||||
FIELD(F_ICMP_TYPE, "icmp_type", FWW_TP_SRC) \
|
FIELD(F_ICMP_TYPE, "icmp_type", FWW_TP_SRC) \
|
||||||
FIELD(F_ICMP_CODE, "icmp_code", FWW_TP_DST)
|
FIELD(F_ICMP_CODE, "icmp_code", FWW_TP_DST) \
|
||||||
|
FIELD(F_ARP_SHA, "arp_sha", FWW_ARP_SHA) \
|
||||||
|
FIELD(F_ARP_THA, "arp_tha", FWW_ARP_THA)
|
||||||
|
|
||||||
enum field_index {
|
enum field_index {
|
||||||
#define FIELD(ENUM, NAME, WILDCARD) ENUM,
|
#define FIELD(ENUM, NAME, WILDCARD) ENUM,
|
||||||
@@ -607,6 +609,16 @@ parse_field_value(struct cls_rule *rule, enum field_index index,
|
|||||||
cls_rule_set_icmp_code(rule, str_to_u32(value));
|
cls_rule_set_icmp_code(rule, str_to_u32(value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case F_ARP_SHA:
|
||||||
|
str_to_mac(value, mac);
|
||||||
|
cls_rule_set_arp_sha(rule, mac);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case F_ARP_THA:
|
||||||
|
str_to_mac(value, mac);
|
||||||
|
cls_rule_set_arp_tha(rule, mac);
|
||||||
|
break;
|
||||||
|
|
||||||
case N_FIELDS:
|
case N_FIELDS:
|
||||||
NOT_REACHED();
|
NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@@ -124,6 +124,10 @@ ofputil_cls_rule_from_match(const struct ofp_match *match,
|
|||||||
/* Initialize most of rule->wc. */
|
/* Initialize most of rule->wc. */
|
||||||
flow_wildcards_init_catchall(wc);
|
flow_wildcards_init_catchall(wc);
|
||||||
wc->wildcards = ofpfw & WC_INVARIANTS;
|
wc->wildcards = ofpfw & WC_INVARIANTS;
|
||||||
|
|
||||||
|
/* Wildcard fields that aren't defined by ofp_match or tun_id. */
|
||||||
|
wc->wildcards |= (FWW_ARP_SHA | FWW_ARP_THA);
|
||||||
|
|
||||||
if (ofpfw & OFPFW_NW_TOS) {
|
if (ofpfw & OFPFW_NW_TOS) {
|
||||||
wc->wildcards |= FWW_NW_TOS;
|
wc->wildcards |= FWW_NW_TOS;
|
||||||
}
|
}
|
||||||
@@ -859,6 +863,11 @@ is_nxm_required(const struct cls_rule *rule, bool cookie_support,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only NXM supports matching ARP hardware addresses. */
|
||||||
|
if (!(wc->wildcards & FWW_ARP_SHA) || !(wc->wildcards & FWW_ARP_THA)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only NXM supports matching registers. */
|
/* Only NXM supports matching registers. */
|
||||||
if (!regs_fully_wildcarded(wc)) {
|
if (!regs_fully_wildcarded(wc)) {
|
||||||
return true;
|
return true;
|
||||||
|
@@ -61,6 +61,7 @@ AT_DATA([flows.txt], [
|
|||||||
tcp,tp_src=123,actions=flood
|
tcp,tp_src=123,actions=flood
|
||||||
in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=drop
|
in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=drop
|
||||||
arp,nw_src=192.168.0.1 actions=drop_spoofed_arp,NORMAL
|
arp,nw_src=192.168.0.1 actions=drop_spoofed_arp,NORMAL
|
||||||
|
arp,dl_src=00:0A:E4:25:6B:B0,arp_sha=00:0A:E4:25:6B:B0 actions=drop
|
||||||
udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0
|
udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0
|
||||||
tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
|
tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
|
||||||
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
||||||
@@ -75,6 +76,7 @@ AT_CHECK([[sed 's/ (xid=0x[0-9a-fA-F]*)//' stdout]], [0], [dnl
|
|||||||
NXT_FLOW_MOD: ADD tcp,tp_src=123 actions=FLOOD
|
NXT_FLOW_MOD: ADD tcp,tp_src=123 actions=FLOOD
|
||||||
NXT_FLOW_MOD: ADD in_port=65534,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=drop
|
NXT_FLOW_MOD: ADD in_port=65534,dl_vlan=9,dl_src=00:0a:e4:25:6b:b0 actions=drop
|
||||||
NXT_FLOW_MOD: ADD arp,nw_src=192.168.0.1 actions=drop_spoofed_arp,NORMAL
|
NXT_FLOW_MOD: ADD arp,nw_src=192.168.0.1 actions=drop_spoofed_arp,NORMAL
|
||||||
|
NXT_FLOW_MOD: ADD arp,dl_src=00:0a:e4:25:6b:b0,arp_sha=00:0a:e4:25:6b:b0 actions=drop
|
||||||
NXT_FLOW_MOD: ADD udp,dl_vlan_pcp=7 idle:5 actions=strip_vlan,output:0
|
NXT_FLOW_MOD: ADD udp,dl_vlan_pcp=7 idle:5 actions=strip_vlan,output:0
|
||||||
NXT_FLOW_MOD: ADD tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
|
NXT_FLOW_MOD: ADD tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
|
||||||
NXT_FLOW_MOD: ADD udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
NXT_FLOW_MOD: ADD udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
||||||
@@ -92,6 +94,7 @@ AT_DATA([flows.txt], [[
|
|||||||
tcp,tp_src=123,actions=flood
|
tcp,tp_src=123,actions=flood
|
||||||
in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=drop
|
in_port=LOCAL dl_vlan=9 dl_src=00:0A:E4:25:6B:B0 actions=drop
|
||||||
arp,nw_src=192.168.0.1 actions=drop_spoofed_arp,NORMAL
|
arp,nw_src=192.168.0.1 actions=drop_spoofed_arp,NORMAL
|
||||||
|
arp,dl_src=00:0A:E4:25:6B:B0,arp_sha=00:0A:E4:25:6B:B0 actions=drop
|
||||||
udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0
|
udp dl_vlan_pcp=7 idle_timeout=5 actions=strip_vlan output:0
|
||||||
tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
|
tcp,nw_src=192.168.0.3,tp_dst=80 actions=set_queue:37,output:1
|
||||||
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
udp,nw_src=192.168.0.3,tp_dst=53 actions=pop_queue,output:1
|
||||||
@@ -106,6 +109,7 @@ AT_CHECK([[sed 's/ (xid=0x[0-9a-fA-F]*)//' stdout]], [0],
|
|||||||
[[NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_SRC(007b) actions=FLOOD
|
[[NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_IP_PROTO(06), NXM_OF_TCP_SRC(007b) actions=FLOOD
|
||||||
NXT_FLOW_MOD: ADD NXM_OF_IN_PORT(fffe), NXM_OF_ETH_SRC(000ae4256bb0), NXM_OF_VLAN_TCI_W(1009/1fff) actions=drop
|
NXT_FLOW_MOD: ADD NXM_OF_IN_PORT(fffe), NXM_OF_ETH_SRC(000ae4256bb0), NXM_OF_VLAN_TCI_W(1009/1fff) actions=drop
|
||||||
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA(c0a80001) actions=drop_spoofed_arp,NORMAL
|
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA(c0a80001) actions=drop_spoofed_arp,NORMAL
|
||||||
|
NXT_FLOW_MOD: ADD NXM_OF_ETH_SRC(000ae4256bb0), NXM_OF_ETH_TYPE(0806), NXM_NX_ARP_SHA(000ae4256bb0) actions=drop
|
||||||
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_VLAN_TCI_W(f000/f000), NXM_OF_IP_PROTO(11) idle:5 actions=strip_vlan,output:0
|
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_VLAN_TCI_W(f000/f000), NXM_OF_IP_PROTO(11) idle:5 actions=strip_vlan,output:0
|
||||||
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_IP_SRC(c0a80003), NXM_OF_IP_PROTO(06), NXM_OF_TCP_DST(0050) actions=set_queue:37,output:1
|
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_IP_SRC(c0a80003), NXM_OF_IP_PROTO(06), NXM_OF_TCP_DST(0050) actions=set_queue:37,output:1
|
||||||
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_IP_SRC(c0a80003), NXM_OF_IP_PROTO(11), NXM_OF_UDP_DST(0035) actions=pop_queue,output:1
|
NXT_FLOW_MOD: ADD NXM_OF_ETH_TYPE(0800), NXM_OF_IP_SRC(c0a80003), NXM_OF_IP_PROTO(11), NXM_OF_UDP_DST(0035) actions=pop_queue,output:1
|
||||||
@@ -205,18 +209,28 @@ NXM_OF_ETH_TYPE(0000) NXM_OF_ARP_OP(0001)
|
|||||||
NXM_OF_ARP_OP(0001)
|
NXM_OF_ARP_OP(0001)
|
||||||
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_OP(0001) NXM_OF_ARP_OP(0001)
|
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_OP(0001) NXM_OF_ARP_OP(0001)
|
||||||
|
|
||||||
# ARP source
|
# ARP source protocol address
|
||||||
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_SPA(ac100014)
|
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_SPA(ac100014)
|
||||||
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_SPA_W(C0a81234/FFFFFF00)
|
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_SPA_W(C0a81234/FFFFFF00)
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_SPA(ac100014)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_SPA(ac100014)
|
||||||
NXM_OF_ARP_SPA_W(C0D8fedc/FFFF0000)
|
NXM_OF_ARP_SPA_W(C0D8fedc/FFFF0000)
|
||||||
|
|
||||||
# ARP destination
|
# ARP destination protocol address
|
||||||
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_TPA(ac100014)
|
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_TPA(ac100014)
|
||||||
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_TPA_W(C0a812fe/FFFFFF00)
|
NXM_OF_ETH_TYPE(0806) NXM_OF_ARP_TPA_W(C0a812fe/FFFFFF00)
|
||||||
NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_TPA(ac100014)
|
NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_TPA(ac100014)
|
||||||
NXM_OF_ARP_TPA_W(C0D80000/FFFF0000)
|
NXM_OF_ARP_TPA_W(C0D80000/FFFF0000)
|
||||||
|
|
||||||
|
# ARP source hardware address
|
||||||
|
NXM_OF_ETH_TYPE(0806) NXM_NX_ARP_SHA(0002e30f80a4)
|
||||||
|
NXM_OF_ETH_TYPE(0800) NXM_NX_ARP_SHA(0002e30f80a4)
|
||||||
|
NXM_NX_ARP_SHA(0002e30f80a4)
|
||||||
|
|
||||||
|
# ARP destination hardware address
|
||||||
|
NXM_OF_ETH_TYPE(0806) NXM_NX_ARP_THA(0002e30f80a4)
|
||||||
|
NXM_OF_ETH_TYPE(0800) NXM_NX_ARP_THA(0002e30f80a4)
|
||||||
|
NXM_NX_ARP_THA(0002e30f80a4)
|
||||||
|
|
||||||
# Tunnel ID.
|
# Tunnel ID.
|
||||||
NXM_NX_TUN_ID(00000000abcdef01)
|
NXM_NX_TUN_ID(00000000abcdef01)
|
||||||
NXM_NX_TUN_ID_W(84200000abcdef01/84200000FFFFFFFF)
|
NXM_NX_TUN_ID_W(84200000abcdef01/84200000FFFFFFFF)
|
||||||
@@ -323,18 +337,28 @@ nx_pull_match() returned error 44010104
|
|||||||
nx_pull_match() returned error 44010104
|
nx_pull_match() returned error 44010104
|
||||||
nx_pull_match() returned error 44010105
|
nx_pull_match() returned error 44010105
|
||||||
|
|
||||||
# ARP source
|
# ARP source protocol address
|
||||||
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA(ac100014)
|
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA(ac100014)
|
||||||
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA_W(c0a81200/ffffff00)
|
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_SPA_W(c0a81200/ffffff00)
|
||||||
nx_pull_match() returned error 44010104
|
nx_pull_match() returned error 44010104
|
||||||
nx_pull_match() returned error 44010104
|
nx_pull_match() returned error 44010104
|
||||||
|
|
||||||
# ARP destination
|
# ARP destination protocol address
|
||||||
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_TPA(ac100014)
|
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_TPA(ac100014)
|
||||||
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_TPA_W(c0a81200/ffffff00)
|
NXM_OF_ETH_TYPE(0806), NXM_OF_ARP_TPA_W(c0a81200/ffffff00)
|
||||||
nx_pull_match() returned error 44010104
|
nx_pull_match() returned error 44010104
|
||||||
nx_pull_match() returned error 44010104
|
nx_pull_match() returned error 44010104
|
||||||
|
|
||||||
|
# ARP source hardware address
|
||||||
|
NXM_OF_ETH_TYPE(0806), NXM_NX_ARP_SHA(0002e30f80a4)
|
||||||
|
nx_pull_match() returned error 44010104
|
||||||
|
nx_pull_match() returned error 44010104
|
||||||
|
|
||||||
|
# ARP destination hardware address
|
||||||
|
NXM_OF_ETH_TYPE(0806), NXM_NX_ARP_THA(0002e30f80a4)
|
||||||
|
nx_pull_match() returned error 44010104
|
||||||
|
nx_pull_match() returned error 44010104
|
||||||
|
|
||||||
# Tunnel ID.
|
# Tunnel ID.
|
||||||
NXM_NX_TUN_ID(00000000abcdef01)
|
NXM_NX_TUN_ID(00000000abcdef01)
|
||||||
NXM_NX_TUN_ID_W(84200000abcdef01/84200000ffffffff)
|
NXM_NX_TUN_ID_W(84200000abcdef01/84200000ffffffff)
|
||||||
|
@@ -345,6 +345,12 @@ Extended Match) extension to OpenFlow. When one of these is specified,
|
|||||||
extension. If the switch does not support NXM, then \fBovs\-ofctl\fR
|
extension. If the switch does not support NXM, then \fBovs\-ofctl\fR
|
||||||
will report a fatal error.
|
will report a fatal error.
|
||||||
.
|
.
|
||||||
|
.IP \fBarp_sha=\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fR
|
||||||
|
.IQ \fBarp_tha=\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fB:\fIxx\fR
|
||||||
|
When \fBdl_type\fR specifies ARP, \fBarp_sha\fR and \fBarp_tha\fR match
|
||||||
|
the source and target hardware address, respectively. An address is
|
||||||
|
specified as 6 pairs of hexadecimal digits delimited by colons.
|
||||||
|
.
|
||||||
.IP \fBtun_id=\fItunnel-id\fR[\fB/\fImask\fR]
|
.IP \fBtun_id=\fItunnel-id\fR[\fB/\fImask\fR]
|
||||||
Matches tunnel identifier \fItunnel-id\fR. Only packets that arrive
|
Matches tunnel identifier \fItunnel-id\fR. Only packets that arrive
|
||||||
over a tunnel that carries a key (e.g. GRE with the RFC 2890 key
|
over a tunnel that carries a key (e.g. GRE with the RFC 2890 key
|
||||||
@@ -506,10 +512,10 @@ Stops processing further actions, if the packet being processed is an
|
|||||||
Ethernet+IPv4 ARP packet for which the source Ethernet address inside
|
Ethernet+IPv4 ARP packet for which the source Ethernet address inside
|
||||||
the ARP packet differs from the source Ethernet address in the
|
the ARP packet differs from the source Ethernet address in the
|
||||||
Ethernet header.
|
Ethernet header.
|
||||||
.
|
.IP
|
||||||
This is useful because OpenFlow does not provide a way to match on the
|
This action is deprecated in favor of defining flows using the
|
||||||
Ethernet addresses inside ARP packets, so there is no other way to
|
\fBarp_sha\fR match field described earlier and will likely be removed
|
||||||
drop spoofed ARPs other than sending every ARP packet to a controller.
|
in a future version of Open vSwitch.
|
||||||
.
|
.
|
||||||
.IP \fBset_queue\fB:\fIqueue\fR
|
.IP \fBset_queue\fB:\fIqueue\fR
|
||||||
Sets the queue that should be used to \fIqueue\fR when packets are
|
Sets the queue that should be used to \fIqueue\fR when packets are
|
||||||
|
Reference in New Issue
Block a user