On Tue, Jul 30, 2013 at 07:49:13PM -0700, Andy Zhou wrote:
> Handling of missing attributes in netlink can be tricky and turns out
> to be error prone. The value (savings in netlink bandwidth) does not
> seem to be significant enough to justify allowing them. This patch
> series make both kernel and userspace always export priority and
> skb_mark attribute. There will be follow on patches in the
> direction of making all attributes explicit.
> 
> Signed-off-by: Andy Zhou <az...@nicira.com>
> ---
>  lib/odp-util.c        |   62 
> +++++++++++++++++++++++++++++++++++++++----------
>  tests/ofproto-dpif.at |   18 +++++++-------
>  2 files changed, 59 insertions(+), 21 deletions(-)
> 
> diff --git a/lib/odp-util.c b/lib/odp-util.c
> index 3c3063d..1f7db2f 100644
> --- a/lib/odp-util.c
> +++ b/lib/odp-util.c
> @@ -926,6 +926,42 @@ odp_mask_attr_is_exact(const struct nlattr *ma)
>      return is_exact;
>  }
>  
> +static bool
> +ommit_format(enum ovs_key_attr attr, const struct nlattr *a,
> +             const struct nlattr *ma)
> +{
> +    switch (attr) {
> +        case OVS_KEY_ATTR_PRIORITY:
> +        case OVS_KEY_ATTR_SKB_MARK:
> +            if (!nl_attr_get_u32(a)) {
> +                if ((!ma) || !nl_attr_get_u32(ma)) {
> +                    return true;  /* Omit output 0 (no mask) or 0/0  */
> +                }
> +            }
> +            break;
> +        case OVS_KEY_ATTR_UNSPEC:
> +        case OVS_KEY_ATTR_ENCAP:
> +        case OVS_KEY_ATTR_TUNNEL:
> +        case OVS_KEY_ATTR_IN_PORT:
> +        case OVS_KEY_ATTR_ETHERNET:
> +        case OVS_KEY_ATTR_VLAN:
> +        case OVS_KEY_ATTR_ETHERTYPE:
> +        case OVS_KEY_ATTR_IPV4:
> +        case OVS_KEY_ATTR_IPV6:
> +        case OVS_KEY_ATTR_TCP:
> +        case OVS_KEY_ATTR_UDP:
> +        case OVS_KEY_ATTR_ICMP:
> +        case OVS_KEY_ATTR_ICMPV6:
> +        case OVS_KEY_ATTR_ARP:
> +        case OVS_KEY_ATTR_ND:
> +        case OVS_KEY_ATTR_MPLS:
> +        case __OVS_KEY_ATTR_MAX:
> +        default:
> +            break;
> +    }
> +
> +    return false;
> +}
>  
>  static void
>  format_odp_key_attr(const struct nlattr *a, const struct nlattr *ma,
> @@ -1345,13 +1381,13 @@ odp_flow_format(const struct nlattr *key, size_t 
> key_len,
>          bool has_ethtype_key = false;
>          const struct nlattr *ma = NULL;
>          struct ofpbuf ofp;
> +        bool first_key = true;
>  
>          ofpbuf_init(&ofp, 100);
>          NL_ATTR_FOR_EACH (a, left, key, key_len) {
> -            if (a != key) {
> -                ds_put_char(ds, ',');
> -            }
> -            if (nl_attr_type(a) == OVS_KEY_ATTR_ETHERTYPE) {
> +            enum ovs_key_attr attr = nl_attr_type(a);
> +
> +            if ( attr == OVS_KEY_ATTR_ETHERTYPE) {
>                  has_ethtype_key = true;
>              }
>              if (mask && mask_len) {
> @@ -1360,8 +1396,14 @@ odp_flow_format(const struct nlattr *key, size_t 
> key_len,
>                      ma = generate_all_wildcard_mask(&ofp, a);
>                  }
>              }
> -            format_odp_key_attr(a, ma, ds);
> -            ofpbuf_clear(&ofp);
> +            if (!ommit_format(attr, a, ma)) {
> +                if (!first_key) {
> +                    ds_put_char(ds, ',');
> +                }
> +                format_odp_key_attr(a, ma, ds);
> +                first_key = false;
> +                ofpbuf_clear(&ofp);
> +            }
>          }
>          ofpbuf_uninit(&ofp);
>  
> @@ -2323,17 +2365,13 @@ odp_flow_key_from_flow__(struct ofpbuf *buf, const 
> struct flow *data,
>       * treat 'data' as a mask. */
>      is_mask = (data != flow);
>  
> -    if (flow->skb_priority) {
> -        nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, data->skb_priority);
> -    }
> +    nl_msg_put_u32(buf, OVS_KEY_ATTR_PRIORITY, data->skb_priority);
>  
>      if (flow->tunnel.ip_dst) {
>          tun_key_to_attr(buf, &data->tunnel);
>      }
>  
> -    if (flow->skb_mark) {
> -        nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->skb_mark);
> -    }
> +    nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->skb_mark);

I came across the skb_mark portion of this problem while re-basing
the recirculation patches. The approach that I took in
included in "Add packet recirculation" v14 is as follows:


    if (flow->skb_mark || data->skb_mark) {
        nl_msg_put_u32(buf, OVS_KEY_ATTR_SKB_MARK, data->skb_mark);
    }

This seemed to ensure that the mark was present in all cases
that it is needed by recirculation without adding it otherwise.
This avoided needing to update the test-suite. However, I think
your more general approach is cleaner, easier to understand,
and should work with recirculation: it suffers if skb_mark is not
present if needed but I don't believe the converse is true.

Reviewed-by: Simon Horman <ho...@verge.net.au>

>      /* Add an ingress port attribute if this is a mask or 'odp_in_port'
>       * is not the magical value "ODPP_NONE". */
> diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
> index 2728a28..3600fb6 100644
> --- a/tests/ofproto-dpif.at
> +++ b/tests/ofproto-dpif.at
> @@ -2088,12 +2088,12 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 
> 'in_port(2),eth(src=50:54:00:00:00:
>  AT_CHECK([ovs-appctl netdev-dummy/receive p3 
> 'in_port(3),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
>  
>  AT_CHECK([ovs-appctl dpif/dump-flows br0 | sort | STRIP_USED], [0], [dnl
> -in_port(1),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> -in_port(2),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=0/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> +skb_priority(0),in_port(1),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> +skb_priority(0),in_port(2),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=0/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
>  ])
>  
>  AT_CHECK([ovs-appctl dpif/dump-flows br1 | sort | STRIP_USED], [0], [dnl
> -in_port(3),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> +skb_priority(0),in_port(3),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
>  ])
>  
>  OVS_VSWITCHD_STOP
> @@ -2110,12 +2110,12 @@ AT_CHECK([ovs-appctl netdev-dummy/receive p2 
> 'in_port(2),eth(src=50:54:00:00:00:
>  AT_CHECK([ovs-appctl netdev-dummy/receive p3 
> 'in_port(3),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)'])
>  
>  AT_CHECK([ovs-appctl dpif/dump-flows br0 | sort | STRIP_USED], [0], [dnl
> -in_port(1),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> -in_port(2),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=0/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> +skb_priority(0),in_port(1),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> +skb_priority(0),in_port(2),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=0/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
>  ])
>  
>  AT_CHECK([ovs-appctl dpif/dump-flows br1 | sort | STRIP_USED], [0], [dnl
> -in_port(3),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> +skb_priority(0),in_port(3),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
>  ])
>  
>  AT_CHECK([ovs-appctl dpif/del-flows br0])
> @@ -2123,7 +2123,7 @@ AT_CHECK([ovs-appctl dpif/dump-flows br0 | sort | 
> STRIP_USED], [0], [dnl
>  ])
>  
>  AT_CHECK([ovs-appctl dpif/dump-flows br1 | sort | STRIP_USED], [0], [dnl
> -in_port(3),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
> +skb_priority(0),in_port(3),eth(src=50:54:00:00:00:09/00:00:00:00:00:00,dst=50:54:00:00:00:0a/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=10.0.0.2/0.0.0.0,dst=10.0.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:0, bytes:0, used:0.0s, actions:userspace(pid=0,slow_path(controller))
>  ])
>  
>  OVS_VSWITCHD_STOP
> @@ -2170,10 +2170,10 @@ dummy@ovs-dummy: hit:13 missed:2
>  ])
>  
>  AT_CHECK([ovs-appctl dpif/dump-flows br0 | STRIP_USED], [0], [dnl
> -in_port(100),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:9, bytes:540, used:0.0s, actions:101,3,2
> +skb_priority(0),in_port(100),eth(src=50:54:00:00:00:05/00:00:00:00:00:00,dst=50:54:00:00:00:07/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.1/0.0.0.0,dst=192.168.0.2/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:9, bytes:540, used:0.0s, actions:101,3,2
>  ]),
>  AT_CHECK([ovs-appctl dpif/dump-flows br1 | STRIP_USED], [0], [dnl
> -in_port(101),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:4, bytes:240, used:0.0s, actions:100,2,3
> +skb_priority(0),in_port(101),eth(src=50:54:00:00:00:07/00:00:00:00:00:00,dst=50:54:00:00:00:05/00:00:00:00:00:00),eth_type(0x0800),ipv4(src=192.168.0.2/0.0.0.0,dst=192.168.0.1/0.0.0.0,proto=1/0,tos=0/0,ttl=64/0,frag=no/0x2),icmp(type=8/0,code=0/0),
>  packets:4, bytes:240, used:0.0s, actions:100,2,3
>  ])
>  
>  AT_CHECK([ovs-ofctl dump-ports br0 pbr0], [0], [dnl
> -- 
> 1.7.9.5
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
> 
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to