[ovs-dev] ip_src_flow

Ben Pfaff blp at nicira.com
Fri Aug 23 20:33:53 UTC 2013


On Fri, Aug 23, 2013 at 12:46:47PM -0700, Jarno Rajahalme wrote:
> On Aug 23, 2013, at 11:26 AM, Ben Pfaff <blp at nicira.com> wrote:
> > Looking at tnl_find() in ofproto/tunnel.c, it maintains the invariant
> > "set <field> to 0 if and only if we set <field>_flow to true", except
> > for <field> = ip_src.  Is that a bug?
> > 
> 
> No, it is not a bug. Tunnel config allows you to leave local address
> unset (=0), allowing the selected route to determine the source
> address to use. Even more, it looks like find_route() in kernel
> might override the source address, even if it is given (in the
> config, or in the flow with _flow set to true).

I see, thanks.

The code might be more obviously correct like this.  If anyone agrees
then I'll check it over and write it up formally.

diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index 202358b..1559b16 100644
*** a/ofproto/tunnel.c
--- b/ofproto/tunnel.c
***************
*** 416,466 ****
  static struct tnl_port *
  tnl_find(struct tnl_match *match_) OVS_REQ_RDLOCK(rwlock)
  {
!     struct tnl_match match = *match_;
!     struct tnl_port *tnl_port;
  
!     /* remote_ip, local_ip, in_key */
!     tnl_port = tnl_find_exact(&match);
!     if (tnl_port) {
!         return tnl_port;
!     }
  
!     /* remote_ip, in_key */
!     match.ip_src = 0;
!     tnl_port = tnl_find_exact(&match);
!     if (tnl_port) {
!         return tnl_port;
!     }
!     match.ip_src = match_->ip_src;
  
!     /* remote_ip, local_ip */
!     match.in_key = 0;
!     match.in_key_flow = true;
!     tnl_port = tnl_find_exact(&match);
!     if (tnl_port) {
!         return tnl_port;
!     }
  
!     /* remote_ip */
!     match.ip_src = 0;
!     tnl_port = tnl_find_exact(&match);
!     if (tnl_port) {
!         return tnl_port;
!     }
  
!     /* Flow-based remote */
!     match.ip_dst = 0;
!     match.ip_dst_flow = true;
!     tnl_port = tnl_find_exact(&match);
!     if (tnl_port) {
!         return tnl_port;
!     }
  
!     /* Flow-based everything */
!     match.ip_src_flow = true;
!     tnl_port = tnl_find_exact(&match);
!     if (tnl_port) {
!         return tnl_port;
      }
  
      return NULL;
--- 416,461 ----
  static struct tnl_port *
  tnl_find(struct tnl_match *match_) OVS_REQ_RDLOCK(rwlock)
  {
!     enum ip_src_type {
!         IP_SRC_EXACT,           /* ip_src must match exactly. */
!         IP_SRC_ANY,             /* Any ip_src is acceptable. */
!         IP_SRC_FLOW             /* ip_src is handled in flow table. */
!     };
! 
!     struct tnl_match_pattern {
!         bool in_key_flow;
!         bool ip_dst_flow;
!         enum ip_src_type ip_src;
!     };
! 
!     static const struct tnl_match_pattern patterns[] = {
!         { false, false, IP_SRC_EXACT }, /* remote_ip, local_ip, in_key. */
!         { false, false, IP_SRC_ANY },   /* remote_ip, in_key. */
!         { true,  false, IP_SRC_EXACT }, /* remote_ip, local_ip. */
!         { true,  false, IP_SRC_ANY },   /* remote_ip. */
!         { true,  true,  IP_SRC_ANY },   /* Flow-based remote. */
!         { true,  true,  IP_SRC_FLOW },  /* Flow-based everything. */
!     };
  
!     struct tnl_match match = *match_;
!     const struct tnl_match_pattern *p;
  
!     for (p = patterns; p < &patterns[ARRAY_SIZE(patterns)]; p++) {
!         struct tnl_port *tnl_port;
  
!         match.in_key_flow = p->in_key_flow;
!         match.in_key = p->in_key_flow ? 0 : match_->in_key;
  
!         match.ip_dst_flow = p->ip_dst_flow;
!         match.ip_dst = p->ip_dst_flow ? 0 : match_->ip_dst_flow;
  
!         match.ip_src_flow = p->ip_src == IP_SRC_FLOW;
!         match.ip_src = p->ip_src == IP_SRC_EXACT ? match_->ip_src : 0;
  
!         tnl_port = tnl_find_exact(&match);
!         if (tnl_port) {
!             return tnl_port;
!         }
      }
  
      return NULL;



More information about the dev mailing list