From 8087f5ff825cae3a699e5a60ca6dd0deb10fc8e5 Mon Sep 17 00:00:00 2001 From: Mehak Mahajan Date: Fri, 2 Nov 2012 11:43:46 -0700 Subject: [PATCH] Process RARP packets with ethertype 0x8035 similar to ARP packets. With this commit, OVS will match the data in the RARP packets having ethertype 0x8035, in the same way as the data in the ARP packets. Signed-off-by: Mehak Mahajan --- NEWS | 3 +- datapath/flow.c | 9 +++-- debian/changelog | 3 +- include/openflow/nicira-ext.h | 6 +-- lib/flow.c | 6 ++- lib/match.c | 17 ++++++--- lib/meta-flow.c | 3 +- lib/nx-match.c | 3 +- lib/odp-util.c | 6 ++- lib/ofp-parse.c | 3 +- lib/ofp-print.c | 5 ++- lib/ofp-util.c | 8 ++-- tests/ofp-print.at | 2 +- tests/ovs-ofctl.at | 70 +++++++++++++++++++++++++++++++++++ utilities/ovs-ofctl.8.in | 25 +++++++++---- 15 files changed, 137 insertions(+), 32 deletions(-) diff --git a/NEWS b/NEWS index c936b61e..dd2ab1e6 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ post-v1.9.0 -------------------- - + - The data in the RARP packets can now be matched in the same way as the + data in ARP packets. v1.9.0 - xx xxx xxxx -------------------- diff --git a/datapath/flow.c b/datapath/flow.c index c70daeed..44e71e62 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -725,7 +725,8 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key, } } - } else if (key->eth.type == htons(ETH_P_ARP) && arphdr_ok(skb)) { + } else if ((key->eth.type == htons(ETH_P_ARP) || + key->eth.type == htons(ETH_P_RARP)) && arphdr_ok(skb)) { struct arp_eth_header *arp; arp = (struct arp_eth_header *)skb_network_header(skb); @@ -1173,7 +1174,8 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp, if (err) return err; } - } else if (swkey->eth.type == htons(ETH_P_ARP)) { + } else if (swkey->eth.type == htons(ETH_P_ARP) || + swkey->eth.type == htons(ETH_P_RARP)) { const struct ovs_key_arp *arp_key; if (!(attrs & (1 << OVS_KEY_ATTR_ARP))) @@ -1361,7 +1363,8 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) ipv6_key->ipv6_tclass = swkey->ip.tos; ipv6_key->ipv6_hlimit = swkey->ip.ttl; ipv6_key->ipv6_frag = swkey->ip.frag; - } else if (swkey->eth.type == htons(ETH_P_ARP)) { + } else if (swkey->eth.type == htons(ETH_P_ARP) || + swkey->eth.type == htons(ETH_P_RARP)) { struct ovs_key_arp *arp_key; nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key)); diff --git a/debian/changelog b/debian/changelog index 39673c64..c366623b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,7 +1,8 @@ openvswitch (1.9.90-1) unstable; urgency=low [ Open vSwitch team ] * New upstream version - - Nothing yet! Try NEWS... + - The data in the RARP packets can now be matched in the same way as the + data in ARP packets. -- Open vSwitch team Wed, 24 Oct 2012 16:12:57 -0700 diff --git a/include/openflow/nicira-ext.h b/include/openflow/nicira-ext.h index e9790fd5..08ed9fc3 100644 --- a/include/openflow/nicira-ext.h +++ b/include/openflow/nicira-ext.h @@ -1516,7 +1516,7 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24); * otherwise. Only ARP opcodes between 1 and 255 should be specified for * matching. * - * Prereqs: NXM_OF_ETH_TYPE must match 0x0806 exactly. + * Prereqs: NXM_OF_ETH_TYPE must match either 0x0806 or 0x8035. * * Format: 16-bit integer in network byte order. * @@ -1526,7 +1526,7 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24); /* For an Ethernet+IP ARP packet, the source or target protocol address * in the ARP header. Always 0 otherwise. * - * Prereqs: NXM_OF_ETH_TYPE must match 0x0806 exactly. + * Prereqs: NXM_OF_ETH_TYPE must match either 0x0806 or 0x8035. * * Format: 32-bit integer in network byte order. * @@ -1593,7 +1593,7 @@ OFP_ASSERT(sizeof(struct nx_action_output_reg) == 24); /* 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. + * Prereqs: NXM_OF_ETH_TYPE must match either 0x0806 or 0x8035. * * Format: 48-bit Ethernet MAC address. * diff --git a/lib/flow.c b/lib/flow.c index 75087c94..7084079e 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -424,7 +424,8 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, packet->l7 = b.data; } } - } else if (flow->dl_type == htons(ETH_TYPE_ARP)) { + } else if (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->dl_type == htons(ETH_TYPE_RARP)) { const struct arp_eth_header *arp = pull_arp(&b); if (arp && arp->ar_hrd == htons(1) && arp->ar_pro == htons(ETH_TYPE_IP) @@ -808,7 +809,8 @@ flow_compose(struct ofpbuf *b, const struct flow *flow) ip->ip_csum = csum(ip, sizeof *ip); } else if (flow->dl_type == htons(ETH_TYPE_IPV6)) { /* XXX */ - } else if (flow->dl_type == htons(ETH_TYPE_ARP)) { + } else if (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->dl_type == htons(ETH_TYPE_RARP)) { struct arp_eth_header *arp; b->l3 = arp = ofpbuf_put_zeros(b, sizeof *arp); diff --git a/lib/match.c b/lib/match.c index 6a4fec72..81b71734 100644 --- a/lib/match.c +++ b/lib/match.c @@ -81,12 +81,14 @@ match_wc_init(struct match *match, const struct flow *flow) memset(&wc->masks.ipv6_dst, 0xff, sizeof wc->masks.ipv6_dst); memset(&wc->masks.ipv6_label, 0xff, sizeof wc->masks.ipv6_label); } else if (flow->dl_type == htons(ETH_TYPE_IP) || - (flow->dl_type == htons(ETH_TYPE_ARP))) { + (flow->dl_type == htons(ETH_TYPE_ARP)) || + (flow->dl_type == htons(ETH_TYPE_RARP))) { memset(&wc->masks.nw_src, 0xff, sizeof wc->masks.nw_src); memset(&wc->masks.nw_dst, 0xff, sizeof wc->masks.nw_dst); } - if (flow->dl_type == htons(ETH_TYPE_ARP)) { + if (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->dl_type == htons(ETH_TYPE_RARP)) { memset(&wc->masks.arp_sha, 0xff, sizeof wc->masks.arp_sha); memset(&wc->masks.arp_tha, 0xff, sizeof wc->masks.arp_tha); } @@ -695,6 +697,8 @@ match_format(const struct match *match, struct ds *s, unsigned int priority) } } else if (f->dl_type == htons(ETH_TYPE_ARP)) { ds_put_cstr(s, "arp,"); + } else if (f->dl_type == htons(ETH_TYPE_RARP)) { + ds_put_cstr(s, "rarp,"); } else { skip_type = false; } @@ -780,7 +784,8 @@ match_format(const struct match *match, struct ds *s, unsigned int priority) ntohl(wc->masks.ipv6_label)); } } - } else if (f->dl_type == htons(ETH_TYPE_ARP)) { + } else if (f->dl_type == htons(ETH_TYPE_ARP) || + f->dl_type == htons(ETH_TYPE_RARP)) { format_ip_netmask(s, "arp_spa", f->nw_src, wc->masks.nw_src); format_ip_netmask(s, "arp_tpa", f->nw_dst, wc->masks.nw_dst); } else { @@ -788,13 +793,15 @@ match_format(const struct match *match, struct ds *s, unsigned int priority) format_ip_netmask(s, "nw_dst", f->nw_dst, wc->masks.nw_dst); } if (!skip_proto && wc->masks.nw_proto) { - if (f->dl_type == htons(ETH_TYPE_ARP)) { + if (f->dl_type == htons(ETH_TYPE_ARP) || + f->dl_type == htons(ETH_TYPE_RARP)) { ds_put_format(s, "arp_op=%"PRIu8",", f->nw_proto); } else { ds_put_format(s, "nw_proto=%"PRIu8",", f->nw_proto); } } - if (f->dl_type == htons(ETH_TYPE_ARP)) { + if (f->dl_type == htons(ETH_TYPE_ARP) || + f->dl_type == htons(ETH_TYPE_RARP)) { format_eth_masked(s, "arp_sha", f->arp_sha, wc->masks.arp_sha); format_eth_masked(s, "arp_tha", f->arp_tha, wc->masks.arp_tha); } diff --git a/lib/meta-flow.c b/lib/meta-flow.c index 4fa05ae7..0b97049a 100644 --- a/lib/meta-flow.c +++ b/lib/meta-flow.c @@ -834,7 +834,8 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow) return true; case MFP_ARP: - return flow->dl_type == htons(ETH_TYPE_ARP); + return (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->dl_type == htons(ETH_TYPE_RARP)); case MFP_IPV4: return flow->dl_type == htons(ETH_TYPE_IP); case MFP_IPV6: diff --git a/lib/nx-match.c b/lib/nx-match.c index 99189940..9c4088f1 100644 --- a/lib/nx-match.c +++ b/lib/nx-match.c @@ -626,7 +626,8 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match, flow->arp_tha, match->wc.masks.arp_tha); } } - } else if (flow->dl_type == htons(ETH_TYPE_ARP)) { + } else if (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->dl_type == htons(ETH_TYPE_RARP)) { /* ARP. */ if (match->wc.masks.nw_proto) { nxm_put_16(b, oxm ? OXM_OF_ARP_OP : NXM_OF_ARP_OP, diff --git a/lib/odp-util.c b/lib/odp-util.c index caf5188e..08823e27 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -1355,7 +1355,8 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow, ipv6_key->ipv6_tclass = flow->nw_tos; ipv6_key->ipv6_hlimit = flow->nw_ttl; ipv6_key->ipv6_frag = ovs_to_odp_frag(flow->nw_frag); - } else if (flow->dl_type == htons(ETH_TYPE_ARP)) { + } else if (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->dl_type == htons(ETH_TYPE_RARP)) { struct ovs_key_arp *arp_key; arp_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_ARP, @@ -1611,7 +1612,8 @@ parse_l3_onward(const struct nlattr *attrs[OVS_KEY_ATTR_MAX + 1], return ODP_FIT_ERROR; } } - } else if (flow->dl_type == htons(ETH_TYPE_ARP)) { + } else if (flow->dl_type == htons(ETH_TYPE_ARP) || + flow->dl_type == htons(ETH_TYPE_RARP)) { expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_ARP; if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_ARP)) { const struct ovs_key_arp *arp_key; diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index dedfb7e2..054db60e 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -720,7 +720,8 @@ parse_protocol(const char *name, const struct protocol **p_out) { "icmp6", ETH_TYPE_IPV6, IPPROTO_ICMPV6 }, { "tcp6", ETH_TYPE_IPV6, IPPROTO_TCP }, { "udp6", ETH_TYPE_IPV6, IPPROTO_UDP }, - }; + { "rarp", ETH_TYPE_RARP, 0}, +}; const struct protocol *p; for (p = protocols; p < &protocols[ARRAY_SIZE(protocols)]; p++) { diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 8654783a..cafc665d 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -617,6 +617,8 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity) } } else if (om->dl_type == htons(ETH_TYPE_ARP)) { ds_put_cstr(&f, "arp,"); + } else if (om->dl_type == htons(ETH_TYPE_RARP)){ + ds_put_cstr(&f, "rarp,"); } else { skip_type = false; } @@ -642,7 +644,8 @@ ofp10_match_to_string(const struct ofp10_match *om, int verbosity) (w & OFPFW10_NW_DST_MASK) >> OFPFW10_NW_DST_SHIFT, verbosity); if (!skip_proto) { - if (om->dl_type == htons(ETH_TYPE_ARP)) { + if (om->dl_type == htons(ETH_TYPE_ARP) || + om->dl_type == htons(ETH_TYPE_RARP)) { print_wild(&f, "arp_op=", w & OFPFW10_NW_PROTO, verbosity, "%u", om->nw_proto); } else { diff --git a/lib/ofp-util.c b/lib/ofp-util.c index 34255da2..b8147686 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -305,7 +305,7 @@ ofputil_match_from_ofp11_match(const struct ofp11_match *ofmatch, uint16_t wc = ntohl(ofmatch->wildcards); uint8_t dl_src_mask[ETH_ADDR_LEN]; uint8_t dl_dst_mask[ETH_ADDR_LEN]; - bool ipv4, arp; + bool ipv4, arp, rarp; int i; match_init_catchall(match); @@ -370,6 +370,7 @@ ofputil_match_from_ofp11_match(const struct ofp11_match *ofmatch, ipv4 = match->flow.dl_type == htons(ETH_TYPE_IP); arp = match->flow.dl_type == htons(ETH_TYPE_ARP); + rarp = match->flow.dl_type == htons(ETH_TYPE_RARP); if (ipv4 && !(wc & OFPFW11_NW_TOS)) { if (ofmatch->nw_tos & ~IP_DSCP_MASK) { @@ -380,7 +381,7 @@ ofputil_match_from_ofp11_match(const struct ofp11_match *ofmatch, match_set_nw_dscp(match, ofmatch->nw_tos); } - if (ipv4 || arp) { + if (ipv4 || arp || rarp) { if (!(wc & OFPFW11_NW_PROTO)) { match_set_nw_proto(match, ofmatch->nw_proto); } @@ -3789,7 +3790,8 @@ ofputil_normalize_match__(struct match *match, bool may_log) may_match |= MAY_ND_TARGET | MAY_ARP_THA; } } - } else if (match->flow.dl_type == htons(ETH_TYPE_ARP)) { + } else if (match->flow.dl_type == htons(ETH_TYPE_ARP) || + match->flow.dl_type == htons(ETH_TYPE_RARP)) { may_match = MAY_NW_PROTO | MAY_NW_ADDR | MAY_ARP_SHA | MAY_ARP_THA; } else { may_match = 0; diff --git a/tests/ofp-print.at b/tests/ofp-print.at index 6133fff6..963f13c9 100644 --- a/tests/ofp-print.at +++ b/tests/ofp-print.at @@ -351,7 +351,7 @@ AT_CHECK([ovs-ofctl ofp-print "\ 00 00 00 23 20 83 c1 5f 00 00 00 00 \ "], [0], [dnl OFPT_PACKET_IN (OF1.2) (xid=0x0): total_len=42 in_port=LOCAL (via no_match) data_len=42 buffer=0xffffff00 -priority=0,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=00:23:20:83:c1:5f,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x8035 +priority=0,rarp,metadata=0,in_port=0,vlan_tci=0x0000,dl_src=00:23:20:83:c1:5f,dl_dst=ff:ff:ff:ff:ff:ff,arp_spa=0.0.0.0,arp_tpa=0.0.0.0,arp_op=3,arp_sha=00:23:20:83:c1:5f,arp_tha=00:23:20:83:c1:5f ]) AT_CLEANUP diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at index 1fa1a342..958982f0 100644 --- a/tests/ovs-ofctl.at +++ b/tests/ovs-ofctl.at @@ -377,6 +377,41 @@ 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) +# RARP opcode +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_OP(0003) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_OP(1111) +NXM_OF_ETH_TYPE(0000) NXM_OF_ARP_OP(0003) +NXM_OF_ARP_OP(0003) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_OP(0003) NXM_OF_ARP_OP(0003) + +# RARP source protocol address +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_SPA(ac100014) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_SPA_W(C0a81234/FFFFFF00) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_SPA_W(C0a81234/aaaaaa00) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_SPA_W(C0a81234/ffffffff) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_SPA_W(C0a81234/00000000) +NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_SPA(ac100014) +NXM_OF_ARP_SPA_W(C0D8fedc/FFFF0000) + +# RARP destination protocol address +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_TPA(ac100014) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_TPA_W(C0a812fe/FFFFFF00) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_TPA_W(C0a81234/77777777) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_TPA_W(C0a81234/ffffffff) +NXM_OF_ETH_TYPE(8035) NXM_OF_ARP_TPA_W(C0a81234/00000000) +NXM_OF_ETH_TYPE(0800) NXM_OF_ARP_TPA(ac100014) +NXM_OF_ARP_TPA_W(C0D80000/FFFF0000) + +# RARP source hardware address +NXM_OF_ETH_TYPE(8035) NXM_NX_ARP_SHA(0002e30f80a4) +NXM_OF_ETH_TYPE(0800) NXM_NX_ARP_SHA(0002e30f80a4) +NXM_NX_ARP_SHA(0002e30f80a4) + +# RARP destination hardware address +NXM_OF_ETH_TYPE(8035) NXM_NX_ARP_THA(0002e30f80a4) +NXM_OF_ETH_TYPE(0800) NXM_NX_ARP_THA(0002e30f80a4) +NXM_NX_ARP_THA(0002e30f80a4) + # IPv6 source NXM_OF_ETH_TYPE(86dd) NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005) NXM_OF_ETH_TYPE(0800) NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005) @@ -629,6 +664,41 @@ NXM_OF_ETH_TYPE(0806), NXM_NX_ARP_THA(0002e30f80a4) nx_pull_match() returned error OFPBMC_BAD_PREREQ nx_pull_match() returned error OFPBMC_BAD_PREREQ +# RARP opcode +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_OP(0003) +nx_pull_match() returned error OFPBMC_BAD_VALUE +nx_pull_match() returned error OFPBMC_BAD_PREREQ +nx_pull_match() returned error OFPBMC_BAD_PREREQ +nx_pull_match() returned error OFPBMC_DUP_FIELD + +# RARP source protocol address +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_SPA(ac100014) +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_SPA_W(c0a81200/ffffff00) +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_SPA_W(80a80200/aaaaaa00) +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_SPA(c0a81234) +NXM_OF_ETH_TYPE(8035) +nx_pull_match() returned error OFPBMC_BAD_PREREQ +nx_pull_match() returned error OFPBMC_BAD_PREREQ + +# RARP destination protocol address +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_TPA(ac100014) +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_TPA_W(c0a81200/ffffff00) +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_TPA_W(40201234/77777777) +NXM_OF_ETH_TYPE(8035), NXM_OF_ARP_TPA(c0a81234) +NXM_OF_ETH_TYPE(8035) +nx_pull_match() returned error OFPBMC_BAD_PREREQ +nx_pull_match() returned error OFPBMC_BAD_PREREQ + +# RARP source hardware address +NXM_OF_ETH_TYPE(8035), NXM_NX_ARP_SHA(0002e30f80a4) +nx_pull_match() returned error OFPBMC_BAD_PREREQ +nx_pull_match() returned error OFPBMC_BAD_PREREQ + +# RARP destination hardware address +NXM_OF_ETH_TYPE(8035), NXM_NX_ARP_THA(0002e30f80a4) +nx_pull_match() returned error OFPBMC_BAD_PREREQ +nx_pull_match() returned error OFPBMC_BAD_PREREQ + # IPv6 source NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005) nx_pull_match() returned error OFPBMC_BAD_PREREQ diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index 9ea09737..7b6939f2 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -468,8 +468,12 @@ When \fBdl_type=0x0806\fR or \fBarp\fR is specified, matches the \fBar_spa\fR or \fBar_tpa\fR field, respectively, in ARP packets for IPv4 and Ethernet. .IP -When \fBdl_type\fR is wildcarded or set to a value other than 0x0800 -or 0x0806, the values of \fBnw_src\fR and \fBnw_dst\fR are ignored +When \fBdl_type=0x8035\fR or \fBrarp\fR is specified, matches the +\fBar_spa\fR or \fBar_tpa\fR field, respectively, in RARP packets for +IPv4 and Ethernet. +.IP +When \fBdl_type\fR is wildcarded or set to a value other than 0x0800, +0x0806, or 0x8035, the values of \fBnw_src\fR and \fBnw_dst\fR are ignored (see \fBFlow Syntax\fR above). . .IP \fBnw_proto=\fIproto\fR @@ -488,9 +492,13 @@ When \fBarp\fR or \fBdl_type=0x0806\fR is specified, matches the lower 8 bits of the ARP opcode. ARP opcodes greater than 255 are treated as 0. .IP +When \fBrarp\fR or \fBdl_type=0x8035\fR is specified, matches the lower +8 bits of the ARP opcode. ARP opcodes greater than 255 are treated as +0. +.IP When \fBdl_type\fR is wildcarded or set to a value other than 0x0800, -0x0806, or 0x86dd, the value of \fBnw_proto\fR is ignored (see \fBFlow -Syntax\fR above). +0x0806, 0x8035 or 0x86dd, the value of \fBnw_proto\fR is ignored (see +\fBFlow Syntax\fR above). . .IP \fBnw_tos=\fItos\fR Matches IP ToS/DSCP or IPv6 traffic class field \fItos\fR, which is @@ -645,6 +653,9 @@ Same as \fBdl_type=0x0800,nw_proto=17\fR. .IP \fBarp\fR Same as \fBdl_type=0x0806\fR. . +.IP \fBrarp\fR +Same as \fBdl_type=0x8035\fR. +. .PP The following field assignments require support for the NXM (Nicira Extended Match) extension to OpenFlow. When one of these is specified, @@ -712,9 +723,9 @@ command, above, for more details. . .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. +When \fBdl_type\fR specifies either ARP or RARP, \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 \fBipv6_src=\fIipv6\fR[\fB/\fInetmask\fR] .IQ \fBipv6_dst=\fIipv6\fR[\fB/\fInetmask\fR] -- 2.30.2