[ovs-dev] [PATCH 2/2] ofproto-dpif: Don't wildcard fields used in special processing.

Justin Pettit jpettit at nicira.com
Tue Jun 18 01:15:52 UTC 2013


A number of fields are looked at when determining whether special
processing (slow-path) is needed.  This commit removes wildcarding when
they were consulted.

Reported-by: Ethan Jackson <ethan at nicira.com>
Reported-by: Paul Ingram <paul at nicira.com>
Signed-off-by: Justin Pettit <jpettit at nicira.com>
---
 lib/bfd.c                    |    5 ++++-
 lib/bfd.h                    |    3 ++-
 lib/cfm.c                    |    8 ++++++--
 lib/cfm.h                    |    4 +++-
 ofproto/ofproto-dpif-xlate.c |   17 ++++++++++-------
 ofproto/ofproto-dpif.c       |    6 ++++--
 ofproto/ofproto-dpif.h       |    2 +-
 7 files changed, 30 insertions(+), 15 deletions(-)

diff --git a/lib/bfd.c b/lib/bfd.c
index 9f671f2..ddf8c4c 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -414,8 +414,11 @@ bfd_put_packet(struct bfd *bfd, struct ofpbuf *p,
 }
 
 bool
-bfd_should_process_flow(const struct flow *flow)
+bfd_should_process_flow(const struct flow *flow, struct flow_wildcards *wc)
 {
+    memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
+    memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
+    memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
     return (flow->dl_type == htons(ETH_TYPE_IP)
             && flow->nw_proto == IPPROTO_UDP
             && flow->tp_dst == htons(3784));
diff --git a/lib/bfd.h b/lib/bfd.h
index 21203b3..61f9945 100644
--- a/lib/bfd.h
+++ b/lib/bfd.h
@@ -23,6 +23,7 @@
 
 struct bfd;
 struct flow;
+struct flow_wildcards;
 struct ofpbuf;
 struct smap;
 
@@ -33,7 +34,7 @@ bool bfd_should_send_packet(const struct bfd *);
 void bfd_put_packet(struct bfd *bfd, struct ofpbuf *packet,
                     uint8_t eth_src[6]);
 
-bool bfd_should_process_flow(const struct flow *);
+bool bfd_should_process_flow(const struct flow *, struct flow_wildcards *);
 void bfd_process_packet(struct bfd *, const struct flow *,
                         const struct ofpbuf *);
 
diff --git a/lib/cfm.c b/lib/cfm.c
index 64ad18c..78aa2bd 100644
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -577,10 +577,14 @@ cfm_set_netdev(struct cfm *cfm, const struct netdev *netdev)
     }
 }
 
-/* Returns true if 'cfm' should process packets from 'flow'. */
+/* Returns true if 'cfm' should process packets from 'flow'.  Sets
+ * fields in 'wc' that were used to make the determination. */
 bool
-cfm_should_process_flow(const struct cfm *cfm, const struct flow *flow)
+cfm_should_process_flow(const struct cfm *cfm, const struct flow *flow,
+                        struct flow_wildcards *wc)
 {
+    memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
+    memset(&wc->masks.dl_type, 0xff, sizeof wc->masks.dl_type);
     return (ntohs(flow->dl_type) == ETH_TYPE_CFM
             && eth_addr_equals(flow->dl_dst, cfm_ccm_addr(cfm))
             && (!cfm->check_tnl_key || flow->tunnel.tun_id == htonll(0)));
diff --git a/lib/cfm.h b/lib/cfm.h
index 057da04..15a0154 100644
--- a/lib/cfm.h
+++ b/lib/cfm.h
@@ -24,6 +24,7 @@
 struct flow;
 struct ofpbuf;
 struct netdev;
+struct flow_wildcards;
 
 #define CFM_RANDOM_VLAN UINT16_MAX
 
@@ -72,7 +73,8 @@ void cfm_compose_ccm(struct cfm *, struct ofpbuf *packet, uint8_t eth_src[6]);
 void cfm_wait(struct cfm *);
 bool cfm_configure(struct cfm *, const struct cfm_settings *);
 void cfm_set_netdev(struct cfm *, const struct netdev *);
-bool cfm_should_process_flow(const struct cfm *cfm, const struct flow *);
+bool cfm_should_process_flow(const struct cfm *cfm, const struct flow *,
+                             struct flow_wildcards *);
 void cfm_process_heartbeat(struct cfm *, const struct ofpbuf *packet);
 int cfm_get_fault(const struct cfm *);
 int cfm_get_health(const struct cfm *);
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 5118d17..f4a027f 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -793,18 +793,21 @@ fix_sflow_action(struct xlate_ctx *ctx)
                          ctx->sflow_odp_port, ctx->sflow_n_outputs, cookie);
 }
 
-static enum slow_path_reason
-process_special(struct ofproto_dpif *ofproto, const struct flow *flow,
+enum slow_path_reason
+process_special(struct xlate_ctx *ctx, const struct flow *flow,
                 const struct ofport_dpif *ofport, const struct ofpbuf *packet)
 {
+    struct ofproto_dpif *ofproto = ctx->ofproto;
+    struct flow_wildcards *wc = &ctx->xout->wc;
+
     if (!ofport) {
         return 0;
-    } else if (ofport->cfm && cfm_should_process_flow(ofport->cfm, flow)) {
+    } else if (ofport->cfm && cfm_should_process_flow(ofport->cfm, flow, wc)) {
         if (packet) {
             cfm_process_heartbeat(ofport->cfm, packet);
         }
         return SLOW_CFM;
-    } else if (ofport->bfd && bfd_should_process_flow(flow)) {
+    } else if (ofport->bfd && bfd_should_process_flow(flow, wc)) {
         if (packet) {
             bfd_process_packet(ofport->bfd, flow, packet);
         }
@@ -815,7 +818,7 @@ process_special(struct ofproto_dpif *ofproto, const struct flow *flow,
             lacp_process_packet(ofport->bundle->lacp, ofport, packet);
         }
         return SLOW_LACP;
-    } else if (ofproto->stp && stp_should_process_flow(flow)) {
+    } else if (ofproto->stp && stp_should_process_flow(flow, wc)) {
         if (packet) {
             stp_process_packet(ofport, packet);
         }
@@ -868,7 +871,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port,
         memset(&flow->tunnel, 0, sizeof flow->tunnel);
         memset(flow->regs, 0, sizeof flow->regs);
 
-        special = process_special(ctx->ofproto, &ctx->xin->flow, peer,
+        special = process_special(ctx, &ctx->xin->flow, peer,
                                   ctx->xin->packet);
         if (special) {
             ctx->xout->slow = special;
@@ -1966,7 +1969,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
     }
 
     in_port = get_ofp_port(ctx.ofproto, flow->in_port);
-    special = process_special(ctx.ofproto, flow, in_port, ctx.xin->packet);
+    special = process_special(&ctx, flow, in_port, ctx.xin->packet);
     if (special) {
         ctx.xout->slow = special;
     } else {
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index e9af4a6..194f5bd 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -1927,10 +1927,12 @@ stp_wait(struct ofproto_dpif *ofproto)
     }
 }
 
-/* Returns true if STP should process 'flow'. */
+/* Returns true if STP should process 'flow'.  Sets fields in 'wc' that
+ * were used to make the determination.*/
 bool
-stp_should_process_flow(const struct flow *flow)
+stp_should_process_flow(const struct flow *flow, struct flow_wildcards *wc)
 {
+    memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
     return eth_addr_equals(flow->dl_dst, eth_addr_stp);
 }
 
diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h
index bfba344..3852fa8 100644
--- a/ofproto/ofproto-dpif.h
+++ b/ofproto/ofproto-dpif.h
@@ -257,7 +257,7 @@ size_t put_userspace_action(const struct ofproto_dpif *,
                             const union user_action_cookie *,
                             const size_t cookie_size);
 
-bool stp_should_process_flow(const struct flow *);
+bool stp_should_process_flow(const struct flow *, struct flow_wildcards *);
 void stp_process_packet(const struct ofport_dpif *,
                         const struct ofpbuf *packet);
 
-- 
1.7.5.4




More information about the dev mailing list