Process RARP packets with ethertype 0x8035 similar to ARP packets.
authorMehak Mahajan <mmahajan@nicira.com>
Fri, 2 Nov 2012 18:43:46 +0000 (11:43 -0700)
committerMehak Mahajan <mmahajan@nicira.com>
Fri, 2 Nov 2012 20:20:16 +0000 (13:20 -0700)
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 <mmahajan@nicira.com>
15 files changed:
NEWS
datapath/flow.c
debian/changelog
include/openflow/nicira-ext.h
lib/flow.c
lib/match.c
lib/meta-flow.c
lib/nx-match.c
lib/odp-util.c
lib/ofp-parse.c
lib/ofp-print.c
lib/ofp-util.c
tests/ofp-print.at
tests/ovs-ofctl.at
utilities/ovs-ofctl.8.in

diff --git a/NEWS b/NEWS
index c936b61e37b2405955df3ef99fd41076c71ec62a..dd2ab1e607e88e337b15df3c15c8bc10d3c6e0be 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 post-v1.9.0
 --------------------
 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
 --------------------
 
 v1.9.0 - xx xxx xxxx
 --------------------
index c70daeed7fa6c3cbe7b528f5fd8d5a74248e681a..44e71e627e4ac83d3162fc1d450cf856213acfe7 100644 (file)
@@ -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);
                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;
                }
                        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)))
                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;
                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));
                struct ovs_key_arp *arp_key;
 
                nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key));
index 39673c6499db135942f409f93a9d0bbbb552a87b..c366623bac8cd732d77e8bf462859f7c90241916 100644 (file)
@@ -1,7 +1,8 @@
 openvswitch (1.9.90-1) unstable; urgency=low
    [ Open vSwitch team ]
    * New upstream version
 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 <dev@openvswitch.org>  Wed, 24 Oct 2012 16:12:57 -0700
 
 
  -- Open vSwitch team <dev@openvswitch.org>  Wed, 24 Oct 2012 16:12:57 -0700
 
index e9790fd5772f14fccaeb0270f2458f39eeafb1d6..08ed9fc36d64a8c02e368bcf68b6d3837149ed48 100644 (file)
@@ -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.
  *
  * 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.
  *
  *
  * 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.
  *
 /* 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.
  *
  *
  * 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.
  *
 /* 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.
  *
  *
  * Format: 48-bit Ethernet MAC address.
  *
index 75087c943515de5747744db787b923ce7a297999..7084079ea778da6dc310b9e242c9a2d0a5a9ea03 100644 (file)
@@ -424,7 +424,8 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority,
                 packet->l7 = b.data;
             }
         }
                 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)
         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 */
         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);
         struct arp_eth_header *arp;
 
         b->l3 = arp = ofpbuf_put_zeros(b, sizeof *arp);
index 6a4fec72f87da44cc8d317b75e1820627ad29bc1..81b717348b5305f9703920ebb06235fca14a2ce7 100644 (file)
@@ -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) ||
         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);
     }
 
         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);
     }
         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_ARP)) {
             ds_put_cstr(s, "arp,");
+        } else if (f->dl_type == htons(ETH_TYPE_RARP)) {
+            ds_put_cstr(s, "rarp,");
         } else {
             skip_type = false;
         }
         } 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));
             }
         }
                               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 {
         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) {
         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);
         }
     }
             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);
     }
         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);
     }
index 4fa05ae74452051530a4185c447063ce9d714550..0b97049a4bd23c5fb49a44b8c2e30321cc2b0af2 100644 (file)
@@ -834,7 +834,8 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow)
         return true;
 
     case MFP_ARP:
         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:
     case MFP_IPV4:
         return flow->dl_type == htons(ETH_TYPE_IP);
     case MFP_IPV6:
index 991899403cc5a7a05333c524204e180a846577b5..9c4088f1a65e86e404594aa3b07621c62c9c8c4b 100644 (file)
@@ -626,7 +626,8 @@ nx_put_raw(struct ofpbuf *b, bool oxm, const struct match *match,
                                    flow->arp_tha, match->wc.masks.arp_tha);
             }
         }
                                    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,
         /* ARP. */
         if (match->wc.masks.nw_proto) {
             nxm_put_16(b, oxm ? OXM_OF_ARP_OP : NXM_OF_ARP_OP,
index caf5188e55cdf0b6a1accf15594ba1c6a307890d..08823e276d2e1e806b3fe7337a124f9bc1f991a1 100644 (file)
@@ -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);
         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,
         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;
             }
         }
                 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;
         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;
index dedfb7e27ca90e4249a1164633e70c394bd2c7b6..054db60e440f73454fb33ca8bd25baed15897589 100644 (file)
@@ -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 },
         { "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++) {
     const struct protocol *p;
 
     for (p = protocols; p < &protocols[ARRAY_SIZE(protocols)]; p++) {
index 8654783a2079c884bfc312cd9ac523b558894287..cafc665d7b10a8104e348e23bbb50e4060d932ee 100644 (file)
@@ -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_ARP)) {
             ds_put_cstr(&f, "arp,");
+        } else if (om->dl_type == htons(ETH_TYPE_RARP)){
+            ds_put_cstr(&f, "rarp,");
         } else {
             skip_type = false;
         }
         } 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) {
                      (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 {
             print_wild(&f, "arp_op=", w & OFPFW10_NW_PROTO, verbosity,
                        "%u", om->nw_proto);
         } else {
index 34255da2f4153bc73c6a1e7323c6ae521f1ba590..b81476869610ce16a050e047d517bec9b96c89d1 100644 (file)
@@ -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];
     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);
     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);
 
     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) {
 
     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);
     }
 
         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);
         }
         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;
             }
         }
                 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;
         may_match = MAY_NW_PROTO | MAY_NW_ADDR | MAY_ARP_SHA | MAY_ARP_THA;
     } else {
         may_match = 0;
index 6133fff6d3397f787370c5cbb62c78c2ae81257b..963f13c9acae830a97d9ced6eb0bca360e60c130 100644 (file)
@@ -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
 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
 
 ])
 AT_CLEANUP
 
index 1fa1a342fc5fcb4d06113cb48d73bd56b6710c98..958982f0aad8b44a8db75e3fb8ae0aa88ba1033c 100644 (file)
@@ -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)
 
 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)
 # 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
 
 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
 # IPv6 source
 NXM_OF_ETH_TYPE(86dd), NXM_NX_IPV6_SRC(20010db83c4d00010002000300040005)
 nx_pull_match() returned error OFPBMC_BAD_PREREQ
index 9ea09737bc276722537a3562aa17f8bd4b5a5e68..7b6939f25ee854d906d2310968418e3025a95fef 100644 (file)
@@ -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
 \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
 (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
 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,
 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
 .
 .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 \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,
 .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
 .
 .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]
 .
 .IP \fBipv6_src=\fIipv6\fR[\fB/\fInetmask\fR]
 .IQ \fBipv6_dst=\fIipv6\fR[\fB/\fInetmask\fR]