Skip to content

Commit 05da589

Browse files
Jarno RajahalmePravin B Shelar
authored andcommitted
openvswitch: Add support for OVS_FLOW_ATTR_PROBE.
This new flag is useful for suppressing error logging while probing for datapath features using flow commands. For backwards compatibility reasons the commands are executed normally, but error logging is suppressed. Signed-off-by: Jarno Rajahalme <[email protected]> Signed-off-by: Pravin B Shelar <[email protected]>
1 parent 12eb18f commit 05da589

File tree

7 files changed

+208
-168
lines changed

7 files changed

+208
-168
lines changed

include/uapi/linux/openvswitch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ enum ovs_flow_attr {
457457
OVS_FLOW_ATTR_USED, /* u64 msecs last used in monotonic time. */
458458
OVS_FLOW_ATTR_CLEAR, /* Flag to clear stats, tcp_flags, used. */
459459
OVS_FLOW_ATTR_MASK, /* Sequence of OVS_KEY_ATTR_* attributes. */
460+
OVS_FLOW_ATTR_PROBE, /* Flow operation is a feature probe, error
461+
* logging should be suppressed. */
460462
__OVS_FLOW_ATTR_MAX
461463
};
462464

net/openvswitch/datapath.c

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
526526
struct vport *input_vport;
527527
int len;
528528
int err;
529+
bool log = !a[OVS_FLOW_ATTR_PROBE];
529530

530531
err = -EINVAL;
531532
if (!a[OVS_PACKET_ATTR_PACKET] || !a[OVS_PACKET_ATTR_KEY] ||
@@ -559,12 +560,12 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
559560
goto err_kfree_skb;
560561

561562
err = ovs_flow_key_extract_userspace(a[OVS_PACKET_ATTR_KEY], packet,
562-
&flow->key);
563+
&flow->key, log);
563564
if (err)
564565
goto err_flow_free;
565566

566567
err = ovs_nla_copy_actions(a[OVS_PACKET_ATTR_ACTIONS],
567-
&flow->key, &acts);
568+
&flow->key, &acts, log);
568569
if (err)
569570
goto err_flow_free;
570571

@@ -855,15 +856,16 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
855856
struct sw_flow_actions *acts;
856857
struct sw_flow_match match;
857858
int error;
859+
bool log = !a[OVS_FLOW_ATTR_PROBE];
858860

859861
/* Must have key and actions. */
860862
error = -EINVAL;
861863
if (!a[OVS_FLOW_ATTR_KEY]) {
862-
OVS_NLERR("Flow key attribute not present in new flow.\n");
864+
OVS_NLERR(log, "Flow key attr not present in new flow.");
863865
goto error;
864866
}
865867
if (!a[OVS_FLOW_ATTR_ACTIONS]) {
866-
OVS_NLERR("Flow actions attribute not present in new flow.\n");
868+
OVS_NLERR(log, "Flow actions attr not present in new flow.");
867869
goto error;
868870
}
869871

@@ -878,18 +880,18 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
878880

879881
/* Extract key. */
880882
ovs_match_init(&match, &new_flow->unmasked_key, &mask);
881-
error = ovs_nla_get_match(&match,
882-
a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]);
883+
error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY],
884+
a[OVS_FLOW_ATTR_MASK], log);
883885
if (error)
884886
goto err_kfree_flow;
885887

886888
ovs_flow_mask_key(&new_flow->key, &new_flow->unmasked_key, &mask);
887889

888890
/* Validate actions. */
889891
error = ovs_nla_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &new_flow->key,
890-
&acts);
892+
&acts, log);
891893
if (error) {
892-
OVS_NLERR("Flow actions may not be safe on all matching packets.\n");
894+
OVS_NLERR(log, "Flow actions may not be safe on all matching packets.");
893895
goto err_kfree_flow;
894896
}
895897

@@ -942,6 +944,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
942944
}
943945
/* The unmasked key has to be the same for flow updates. */
944946
if (unlikely(!ovs_flow_cmp_unmasked_key(flow, &match))) {
947+
/* Look for any overlapping flow. */
945948
flow = ovs_flow_tbl_lookup_exact(&dp->table, &match);
946949
if (!flow) {
947950
error = -ENOENT;
@@ -984,16 +987,18 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
984987
/* Factor out action copy to avoid "Wframe-larger-than=1024" warning. */
985988
static struct sw_flow_actions *get_flow_actions(const struct nlattr *a,
986989
const struct sw_flow_key *key,
987-
const struct sw_flow_mask *mask)
990+
const struct sw_flow_mask *mask,
991+
bool log)
988992
{
989993
struct sw_flow_actions *acts;
990994
struct sw_flow_key masked_key;
991995
int error;
992996

993997
ovs_flow_mask_key(&masked_key, key, mask);
994-
error = ovs_nla_copy_actions(a, &masked_key, &acts);
998+
error = ovs_nla_copy_actions(a, &masked_key, &acts, log);
995999
if (error) {
996-
OVS_NLERR("Actions may not be safe on all matching packets.\n");
1000+
OVS_NLERR(log,
1001+
"Actions may not be safe on all matching packets");
9971002
return ERR_PTR(error);
9981003
}
9991004

@@ -1012,23 +1017,25 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
10121017
struct sw_flow_actions *old_acts = NULL, *acts = NULL;
10131018
struct sw_flow_match match;
10141019
int error;
1020+
bool log = !a[OVS_FLOW_ATTR_PROBE];
10151021

10161022
/* Extract key. */
10171023
error = -EINVAL;
10181024
if (!a[OVS_FLOW_ATTR_KEY]) {
1019-
OVS_NLERR("Flow key attribute not present in set flow.\n");
1025+
OVS_NLERR(log, "Flow key attribute not present in set flow.");
10201026
goto error;
10211027
}
10221028

10231029
ovs_match_init(&match, &key, &mask);
1024-
error = ovs_nla_get_match(&match,
1025-
a[OVS_FLOW_ATTR_KEY], a[OVS_FLOW_ATTR_MASK]);
1030+
error = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY],
1031+
a[OVS_FLOW_ATTR_MASK], log);
10261032
if (error)
10271033
goto error;
10281034

10291035
/* Validate actions. */
10301036
if (a[OVS_FLOW_ATTR_ACTIONS]) {
1031-
acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask);
1037+
acts = get_flow_actions(a[OVS_FLOW_ATTR_ACTIONS], &key, &mask,
1038+
log);
10321039
if (IS_ERR(acts)) {
10331040
error = PTR_ERR(acts);
10341041
goto error;
@@ -1109,14 +1116,16 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
11091116
struct datapath *dp;
11101117
struct sw_flow_match match;
11111118
int err;
1119+
bool log = !a[OVS_FLOW_ATTR_PROBE];
11121120

11131121
if (!a[OVS_FLOW_ATTR_KEY]) {
1114-
OVS_NLERR("Flow get message rejected, Key attribute missing.\n");
1122+
OVS_NLERR(log,
1123+
"Flow get message rejected, Key attribute missing.");
11151124
return -EINVAL;
11161125
}
11171126

11181127
ovs_match_init(&match, &key, NULL);
1119-
err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL);
1128+
err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL, log);
11201129
if (err)
11211130
return err;
11221131

@@ -1157,10 +1166,12 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
11571166
struct datapath *dp;
11581167
struct sw_flow_match match;
11591168
int err;
1169+
bool log = !a[OVS_FLOW_ATTR_PROBE];
11601170

11611171
if (likely(a[OVS_FLOW_ATTR_KEY])) {
11621172
ovs_match_init(&match, &key, NULL);
1163-
err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL);
1173+
err = ovs_nla_get_match(&match, a[OVS_FLOW_ATTR_KEY], NULL,
1174+
log);
11641175
if (unlikely(err))
11651176
return err;
11661177
}
@@ -1250,8 +1261,10 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
12501261

12511262
static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
12521263
[OVS_FLOW_ATTR_KEY] = { .type = NLA_NESTED },
1264+
[OVS_FLOW_ATTR_MASK] = { .type = NLA_NESTED },
12531265
[OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED },
12541266
[OVS_FLOW_ATTR_CLEAR] = { .type = NLA_FLAG },
1267+
[OVS_FLOW_ATTR_PROBE] = { .type = NLA_FLAG },
12551268
};
12561269

12571270
static const struct genl_ops dp_flow_genl_ops[] = {

net/openvswitch/datapath.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ void ovs_dp_notify_wq(struct work_struct *work);
199199
int action_fifos_init(void);
200200
void action_fifos_exit(void);
201201

202-
#define OVS_NLERR(fmt, ...) \
202+
#define OVS_NLERR(logging_allowed, fmt, ...) \
203203
do { \
204-
if (net_ratelimit()) \
205-
pr_info("netlink: " fmt, ##__VA_ARGS__); \
204+
if (logging_allowed && net_ratelimit()) \
205+
pr_info("netlink: " fmt "\n", ##__VA_ARGS__); \
206206
} while (0)
207207
#endif /* datapath.h */

net/openvswitch/flow.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -712,12 +712,12 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info,
712712

713713
int ovs_flow_key_extract_userspace(const struct nlattr *attr,
714714
struct sk_buff *skb,
715-
struct sw_flow_key *key)
715+
struct sw_flow_key *key, bool log)
716716
{
717717
int err;
718718

719719
/* Extract metadata from netlink attributes. */
720-
err = ovs_nla_get_flow_metadata(attr, key);
720+
err = ovs_nla_get_flow_metadata(attr, key, log);
721721
if (err)
722722
return err;
723723

net/openvswitch/flow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,6 @@ int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info,
257257
/* Extract key from packet coming from userspace. */
258258
int ovs_flow_key_extract_userspace(const struct nlattr *attr,
259259
struct sk_buff *skb,
260-
struct sw_flow_key *key);
260+
struct sw_flow_key *key, bool log);
261261

262262
#endif /* flow.h */

0 commit comments

Comments
 (0)