From 43f9ac0aa92656272f73e923f7424fe07ec56988 Mon Sep 17 00:00:00 2001 From: Jarno Rajahalme Date: Fri, 12 Sep 2014 11:20:13 -0700 Subject: [PATCH] dpif: Use OVS_FLOW_ATTR_PROBE. Use the new OVS_FLOW_ATTR_PROBE flag when probing for datapath feature support. Suppress also dpif error logging when requested, as probe failures are already logged at ofproto-dpif. Signed-off-by: Jarno Rajahalme Acked-by: Ben Pfaff --- lib/dpif-netlink.c | 11 +++++++++++ lib/dpif.c | 6 ++++-- lib/dpif.h | 4 +++- ofproto/ofproto-dpif-upcall.c | 1 + ofproto/ofproto-dpif.c | 7 +++++-- 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 029c4d1b5..67c2814c7 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -115,6 +115,7 @@ struct dpif_netlink_flow { const uint8_t *tcp_flags; /* OVS_FLOW_ATTR_TCP_FLAGS. */ const ovs_32aligned_u64 *used; /* OVS_FLOW_ATTR_USED. */ bool clear; /* OVS_FLOW_ATTR_CLEAR. */ + bool probe; /* OVS_FLOW_ATTR_PROBE. */ }; static void dpif_netlink_flow_init(struct dpif_netlink_flow *); @@ -1127,6 +1128,9 @@ dpif_netlink_init_flow_put(struct dpif_netlink *dpif, if (put->flags & DPIF_FP_ZERO_STATS) { request->clear = true; } + if (put->flags & DPIF_FP_PROBE) { + request->probe = true; + } request->nlmsg_flags = put->flags & DPIF_FP_MODIFY ? 0 : NLM_F_CREATE; } @@ -1333,6 +1337,9 @@ dpif_netlink_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec, nl_msg_put_unspec(buf, OVS_PACKET_ATTR_ACTIONS, d_exec->actions, d_exec->actions_len); + if (d_exec->probe) { + nl_msg_put_flag(buf, OVS_FLOW_ATTR_PROBE); + } } #define MAX_OPS 50 @@ -2328,6 +2335,7 @@ dpif_netlink_flow_from_ofpbuf(struct dpif_netlink_flow *flow, [OVS_FLOW_ATTR_TCP_FLAGS] = { .type = NL_A_U8, .optional = true }, [OVS_FLOW_ATTR_USED] = { .type = NL_A_U64, .optional = true }, /* The kernel never uses OVS_FLOW_ATTR_CLEAR. */ + /* The kernel never uses OVS_FLOW_ATTR_PROBE. */ }; struct nlattr *a[ARRAY_SIZE(ovs_flow_policy)]; @@ -2410,6 +2418,9 @@ dpif_netlink_flow_to_ofpbuf(const struct dpif_netlink_flow *flow, if (flow->clear) { nl_msg_put_flag(buf, OVS_FLOW_ATTR_CLEAR); } + if (flow->probe) { + nl_msg_put_flag(buf, OVS_FLOW_ATTR_PROBE); + } } /* Clears 'flow' to "empty" values. */ diff --git a/lib/dpif.c b/lib/dpif.c index bdefdcc56..91e9baf61 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1026,6 +1026,7 @@ dpif_execute_helper_cb(void *aux_, struct dpif_packet **packets, int cnt, execute.packet = packet; execute.md = *md; execute.needs_help = false; + execute.probe = false; aux->error = dpif_execute(aux->dpif, &execute); log_execute_message(aux->dpif, &execute, true, aux->error); @@ -1502,7 +1503,7 @@ static void log_flow_put_message(struct dpif *dpif, const struct dpif_flow_put *put, int error) { - if (should_log_flow_message(error)) { + if (should_log_flow_message(error) && !(put->flags & DPIF_FP_PROBE)) { struct ds s; ds_init(&s); @@ -1554,7 +1555,8 @@ static void log_execute_message(struct dpif *dpif, const struct dpif_execute *execute, bool subexecute, int error) { - if (!(error ? VLOG_DROP_WARN(&error_rl) : VLOG_DROP_DBG(&dpmsg_rl))) { + if (!(error ? VLOG_DROP_WARN(&error_rl) : VLOG_DROP_DBG(&dpmsg_rl)) + && !execute->probe) { struct ds ds = DS_EMPTY_INITIALIZER; char *packet; diff --git a/lib/dpif.h b/lib/dpif.h index c57c8b01f..f88fa78d8 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -511,7 +511,8 @@ void dpif_flow_stats_format(const struct dpif_flow_stats *, struct ds *); enum dpif_flow_put_flags { DPIF_FP_CREATE = 1 << 0, /* Allow creating a new flow. */ DPIF_FP_MODIFY = 1 << 1, /* Allow modifying an existing flow. */ - DPIF_FP_ZERO_STATS = 1 << 2 /* Zero the stats of an existing flow. */ + DPIF_FP_ZERO_STATS = 1 << 2, /* Zero the stats of an existing flow. */ + DPIF_FP_PROBE = 1 << 3 /* Suppress error messages, if any. */ }; int dpif_flow_flush(struct dpif *); @@ -662,6 +663,7 @@ struct dpif_execute { const struct nlattr *actions; /* Actions to execute on packet. */ size_t actions_len; /* Length of 'actions' in bytes. */ bool needs_help; + bool probe; /* Suppress error messages. */ /* Input, but possibly modified as a side effect of execution. */ struct ofpbuf *packet; /* Packet to execute. */ diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c index c9dabc2b6..5fc647e0b 100644 --- a/ofproto/ofproto-dpif-upcall.c +++ b/ofproto/ofproto-dpif-upcall.c @@ -1138,6 +1138,7 @@ handle_upcalls(struct udpif *udpif, struct upcall *upcalls, op->u.execute.actions = ofpbuf_data(upcall->xout.odp_actions); op->u.execute.actions_len = ofpbuf_size(upcall->xout.odp_actions); op->u.execute.needs_help = (upcall->xout.slow & SLOW_ACTION) != 0; + op->u.execute.probe = false; } } diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 1d964ddc8..d965d3851 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -992,7 +992,7 @@ check_recirc(struct dpif_backer *backer) ofpbuf_use_stack(&key, &keybuf, sizeof keybuf); odp_flow_key_from_flow(&key, &flow, NULL, 0, true); - error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE, + error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_PROBE, ofpbuf_data(&key), ofpbuf_size(&key), NULL, 0, NULL, 0, NULL); if (error && error != EEXIST) { @@ -1068,6 +1068,7 @@ check_variable_length_userdata(struct dpif_backer *backer) execute.packet = &packet; execute.md = PKT_METADATA_INITIALIZER(0); execute.needs_help = false; + execute.probe = true; error = dpif_execute(backer->dpif, &execute); @@ -1120,7 +1121,7 @@ check_max_mpls_depth(struct dpif_backer *backer) ofpbuf_use_stack(&key, &keybuf, sizeof keybuf); odp_flow_key_from_flow(&key, &flow, NULL, 0, false); - error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE, + error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_PROBE, ofpbuf_data(&key), ofpbuf_size(&key), NULL, 0, NULL, 0, NULL); if (error && error != EEXIST) { @@ -1179,6 +1180,7 @@ check_masked_set_action(struct dpif_backer *backer) execute.packet = &packet; execute.md = PKT_METADATA_INITIALIZER(0); execute.needs_help = false; + execute.probe = true; error = dpif_execute(backer->dpif, &execute); @@ -3482,6 +3484,7 @@ ofproto_dpif_execute_actions(struct ofproto_dpif *ofproto, execute.packet = packet; execute.md = pkt_metadata_from_flow(flow); execute.needs_help = (xout.slow & SLOW_ACTION) != 0; + execute.probe = false; /* Fix up in_port. */ in_port = flow->in_port.ofp_port;