It looks good overall. Thanks for working on this. Signed-off-by: Andy Zhou <az...@nicira.com>
I have a few minor comments: In datapatch.c, should we extend flow_policy[] for the new flow attributes? It seems OVS_fLOW_ATTR_MASK is also missing -- may be good to fix that also. in flow_netlink.c for function ovs_nla_get_flow_metadata and ovs_nla_get_match. It may be good to add comment about the newly added argument. in ovs_nla_get_match() in the mask section of parsing OVS_KEY_ATTR_ENCAP, the parse_flow_mask_nlattrs(encap ...) call is longer than 80 characters. On Wed, Sep 10, 2014 at 2:06 PM, Jarno Rajahalme <jrajaha...@nicira.com> wrote: > This new flag is useful for suppressing error logging when error > messages may be expected, as when probing for datapath features using > flow commands. > > Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> > --- > datapath/datapath.c | 26 +++++++++------ > datapath/datapath.h | 6 ++++ > datapath/flow.c | 4 +-- > datapath/flow.h | 2 +- > datapath/flow_netlink.c | 36 > ++++++++++++--------- > datapath/flow_netlink.h | 8 ++--- > datapath/linux/compat/include/linux/openvswitch.h | 3 ++ > 7 files changed, 52 insertions(+), 33 deletions(-) > > diff --git a/datapath/datapath.c b/datapath/datapath.c > index 59f73d7..30e082d 100644 > --- a/datapath/datapath.c > +++ b/datapath/datapath.c > @@ -525,6 +525,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, > struct genl_info *info) > struct vport *input_vport; > int len; > int err; > + bool log = !a[OVS_FLOW_ATTR_SILENT]; > > err = -EINVAL; > if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] || > @@ -558,7 +559,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, > struct genl_info *info) > goto err_kfree_skb; > > err = ovs_flow_key_extract_userspace(a[OVS_PACKET_ATTR_KEY], packet, > - &flow->key); > + &flow->key, log); > if (err) > goto err_flow_free; > > @@ -855,15 +856,16 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct > genl_info *info) > struct sw_flow_actions *acts; > struct sw_flow_match match; > int error; > + bool log = !a[OVS_FLOW_ATTR_SILENT]; > > /* Must have key and actions. */ > error = -EINVAL; > if (!a[OVS_FLOW_ATTR_KEY]) { > - OVS_NLERR("Flow key attribute not present in new flow.\n"); > + OVS_NLERR_IF(log, "Flow key attribute not present in new > flow.\n"); > goto error; > } > if (!a[OVS_FLOW_ATTR_ACTIONS]) { > - OVS_NLERR("Flow actions attribute not present in new > flow.\n"); > + OVS_NLERR_IF(log, "Flow actions attribute not present in new > flow.\n"); > goto error; > } > > @@ -877,8 +879,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct > genl_info *info) > > /* Extract key. */ > ovs_match_init(&match, &new_flow->unmasked_key, &mask); > - error = ovs_nla_get_match(&match, > - a[OVS_FLOW_ATTR_KEY], > a[OVS_FLOW_ATTR_MASK]); > + error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], > + a[OVS_FLOW_ATTR_MASK], log); > if (error) > goto err_kfree_flow; > > @@ -888,7 +890,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct > genl_info *info) > error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key, > &acts); > if (error) { > - OVS_NLERR("Flow actions may not be safe on all matching > packets.\n"); > + OVS_NLERR_IF(log, "Flow actions may not be safe on all > matching packets.\n"); > goto err_kfree_acts; > } > > @@ -1012,6 +1014,7 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct > genl_info *info) > struct sw_flow_actions *old_acts = NULL, *acts = NULL; > struct sw_flow_match match; > int error; > + bool log = !a[OVS_FLOW_ATTR_SILENT]; > > /* Extract key. */ > error = -EINVAL; > @@ -1021,8 +1024,8 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct > genl_info *info) > } > > ovs_match_init(&match, &key, &mask); > - error = ovs_nla_get_match(&match, > - a[OVS_FLOW_ATTR_KEY], > a[OVS_FLOW_ATTR_MASK]); > + error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], > + a[OVS_FLOW_ATTR_MASK], log); > if (error) > goto error; > > @@ -1109,6 +1112,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct > genl_info *info) > struct datapath *dp; > struct sw_flow_match match; > int err; > + bool log = !a[OVS_FLOW_ATTR_SILENT]; > > if (!a[OVS_FLOW_ATTR_KEY]) { > OVS_NLERR("Flow get message rejected, Key attribute > missing.\n"); > @@ -1116,7 +1120,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct > genl_info *info) > } > > ovs_match_init(&match, &key, NULL); > - err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL); > + err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, log); > if (err) > return err; > > @@ -1157,10 +1161,12 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, > struct genl_info *info) > struct datapath *dp; > struct sw_flow_match match; > int err; > + bool log = !a[OVS_FLOW_ATTR_SILENT]; > > if (likely(a[OVS_FLOW_ATTR_KEY])) { > ovs_match_init(&match, &key, NULL); > - err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL); > + err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, > + log); > if (unlikely(err)) > return err; > } > diff --git a/datapath/datapath.h b/datapath/datapath.h > index c5d3c86..1b8db14 100644 > --- a/datapath/datapath.h > +++ b/datapath/datapath.h > @@ -209,4 +209,10 @@ do { > \ > if (net_ratelimit()) \ > pr_info("netlink: " fmt, ##__VA_ARGS__); \ > } while (0) > + > +#define OVS_NLERR_IF(logging_allowed, fmt, ...) \ > +do { \ > + if (logging_allowed) \ > + OVS_NLERR(fmt, ##__VA_ARGS__); \ > +} while (0) > #endif /* datapath.h */ > diff --git a/datapath/flow.c b/datapath/flow.c > index 12ebc5b..84a85c4 100644 > --- a/datapath/flow.c > +++ b/datapath/flow.c > @@ -712,12 +712,12 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info > *tun_info, > > int ovs_flow_key_extract_userspace(const struct nlattr *attr, > struct sk_buff *skb, > - struct sw_flow_key *key) > + struct sw_flow_key *key, bool log) > { > int err; > > /* Extract metadata from netlink attributes. */ > - err = ovs_nla_get_flow_metadata(attr, key); > + err = ovs_nla_get_flow_metadata(attr, key, log); > if (err) > return err; > > diff --git a/datapath/flow.h b/datapath/flow.h > index 44ed10d..b25ab87 100644 > --- a/datapath/flow.h > +++ b/datapath/flow.h > @@ -257,7 +257,7 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info > *tun_info, > /* Extract key from packet coming from userspace. */ > int ovs_flow_key_extract_userspace(const struct nlattr *attr, > struct sk_buff *skb, > - struct sw_flow_key *key); > + struct sw_flow_key *key, bool log); > /* Update the non-metadata part of the flow key using skb. */ > int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key); > > diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c > index 6c74841..5c24376 100644 > --- a/datapath/flow_netlink.c > +++ b/datapath/flow_netlink.c > @@ -327,7 +327,7 @@ static bool is_all_zero(const u8 *fp, size_t size) > > static int __parse_flow_nlattrs(const struct nlattr *attr, > const struct nlattr *a[], > - u64 *attrsp, bool nz) > + u64 *attrsp, bool log, bool nz) > { > const struct nlattr *nla; > u64 attrs; > @@ -339,19 +339,19 @@ static int __parse_flow_nlattrs(const struct nlattr > *attr, > int expected_len; > > if (type > OVS_KEY_ATTR_MAX) { > - OVS_NLERR("Unknown key attribute (type=%d, > max=%d).\n", > + OVS_NLERR_IF(log, "Unknown key attribute (type=%d, > max=%d).\n", > type, OVS_KEY_ATTR_MAX); > return -EINVAL; > } > > if (attrs & (1ULL << type)) { > - OVS_NLERR("Duplicate key attribute (type %d).\n", > type); > + OVS_NLERR_IF(log, "Duplicate key attribute (type > %d).\n", type); > return -EINVAL; > } > > expected_len = ovs_key_lens[type]; > if (nla_len(nla) != expected_len && expected_len != -1) { > - OVS_NLERR("Key attribute has unexpected length > (type=%d" > + OVS_NLERR_IF(log, "Key attribute has unexpected > length (type=%d" > ", length=%d, expected=%d).\n", type, > nla_len(nla), expected_len); > return -EINVAL; > @@ -363,7 +363,7 @@ static int __parse_flow_nlattrs(const struct nlattr *attr, > } > } > if (rem) { > - OVS_NLERR("Message has %d unknown bytes.\n", rem); > + OVS_NLERR_IF(log, "Message has %d unknown bytes.\n", rem); > return -EINVAL; > } > > @@ -372,15 +372,17 @@ static int __parse_flow_nlattrs(const struct nlattr > *attr, > } > > static int parse_flow_mask_nlattrs(const struct nlattr *attr, > - const struct nlattr *a[], u64 *attrsp) > + const struct nlattr *a[], u64 *attrsp, > + bool log) > { > - return __parse_flow_nlattrs(attr, a, attrsp, true); > + return __parse_flow_nlattrs(attr, a, attrsp, log, true); > } > > static int parse_flow_nlattrs(const struct nlattr *attr, > - const struct nlattr *a[], u64 *attrsp) > + const struct nlattr *a[], u64 *attrsp, > + bool log) > { > - return __parse_flow_nlattrs(attr, a, attrsp, false); > + return __parse_flow_nlattrs(attr, a, attrsp, log, false); > } > > static int ipv4_tun_from_nlattr(const struct nlattr *attr, > @@ -932,7 +934,8 @@ static void mask_set_nlattr(struct nlattr *attr, u8 val) > */ > int ovs_nla_get_match(struct sw_flow_match *match, > const struct nlattr *nla_key, > - const struct nlattr *nla_mask) > + const struct nlattr *nla_mask, > + bool log) > { > const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; > const struct nlattr *encap; > @@ -942,7 +945,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, > bool encap_valid = false; > int err; > > - err = parse_flow_nlattrs(nla_key, a, &key_attrs); > + err = parse_flow_nlattrs(nla_key, a, &key_attrs, log); > if (err) > return err; > > @@ -964,7 +967,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, > encap_valid = true; > > if (tci & htons(VLAN_TAG_PRESENT)) { > - err = parse_flow_nlattrs(encap, a, &key_attrs); > + err = parse_flow_nlattrs(encap, a, &key_attrs, log); > if (err) > return err; > } else if (!tci) { > @@ -1014,7 +1017,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, > nla_mask = newmask; > } > > - err = parse_flow_mask_nlattrs(nla_mask, a, &mask_attrs); > + err = parse_flow_mask_nlattrs(nla_mask, a, &mask_attrs, log); > if (err) > goto free_newmask; > > @@ -1038,7 +1041,7 @@ int ovs_nla_get_match(struct sw_flow_match *match, > if (eth_type == htons(0xffff)) { > mask_attrs &= ~(1ULL << > OVS_KEY_ATTR_ETHERTYPE); > encap = a[OVS_KEY_ATTR_ENCAP]; > - err = parse_flow_mask_nlattrs(encap, a, > &mask_attrs); > + err = parse_flow_mask_nlattrs(encap, a, > &mask_attrs, log); > if (err) > goto free_newmask; > } else { > @@ -1083,14 +1086,15 @@ free_newmask: > * extracted from the packet itself. > */ > int ovs_nla_get_flow_metadata(const struct nlattr *attr, > - struct sw_flow_key *key) > + struct sw_flow_key *key, > + bool log) > { > const struct nlattr *a[OVS_KEY_ATTR_MAX + 1]; > struct sw_flow_match match; > u64 attrs = 0; > int err; > > - err = parse_flow_nlattrs(attr, a, &attrs); > + err = parse_flow_nlattrs(attr, a, &attrs, log); > if (err) > return -EINVAL; > > diff --git a/datapath/flow_netlink.h b/datapath/flow_netlink.h > index 90bbe37..2cf15c2 100644 > --- a/datapath/flow_netlink.h > +++ b/datapath/flow_netlink.h > @@ -45,11 +45,11 @@ void ovs_match_init(struct sw_flow_match *match, > > int ovs_nla_put_flow(const struct sw_flow_key *, > const struct sw_flow_key *, struct sk_buff *); > -int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *); > +int ovs_nla_get_flow_metadata(const struct nlattr *, struct sw_flow_key *, > + bool log); > > -int ovs_nla_get_match(struct sw_flow_match *match, > - const struct nlattr *, > - const struct nlattr *); > +int ovs_nla_get_match(struct sw_flow_match *, const struct nlattr *key, > + const struct nlattr *mask, bool log); > int ovs_nla_put_egress_tunnel_key(struct sk_buff *, > const struct ovs_tunnel_info *); > > diff --git a/datapath/linux/compat/include/linux/openvswitch.h > b/datapath/linux/compat/include/linux/openvswitch.h > index 306ea86..14c05fc 100644 > --- a/datapath/linux/compat/include/linux/openvswitch.h > +++ b/datapath/linux/compat/include/linux/openvswitch.h > @@ -483,6 +483,9 @@ enum ovs_flow_attr { > OVS_FLOW_ATTR_USED, /* u64 msecs last used in monotonic time. */ > OVS_FLOW_ATTR_CLEAR, /* Flag to clear stats, tcp_flags, used. */ > OVS_FLOW_ATTR_MASK, /* Sequence of OVS_KEY_ATTR_* attributes. */ > + OVS_FLOW_ATTR_SILENT, /* Flag to suppress any logging for the flow > + * operation, useful when probing for feature > + * compatibility. */ > __OVS_FLOW_ATTR_MAX > }; > > -- > 1.7.10.4 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev