Skip to content

Commit 69929d4

Browse files
chaudronkuba-moo
authored andcommitted
net: openvswitch: fix TTL decrement action netlink message format
Currently, the openvswitch module is not accepting the correctly formated netlink message for the TTL decrement action. For both setting and getting the dec_ttl action, the actions should be nested in the OVS_DEC_TTL_ATTR_ACTION attribute as mentioned in the openvswitch.h uapi. When the original patch was sent, it was tested with a private OVS userspace implementation. This implementation was unfortunately not upstreamed and reviewed, hence an erroneous version of this patch was sent out. Leaving the patch as-is would cause problems as the kernel module could interpret additional attributes as actions and vice-versa, due to the actions not being encapsulated/nested within the actual attribute, but being concatinated after it. Fixes: 744676e ("openvswitch: add TTL decrement action") Signed-off-by: Eelco Chaudron <echaudro@redhat.com> Link: https://lore.kernel.org/r/160622121495.27296.888010441924340582.stgit@wsfd-netdev64.ntdv.lab.eng.bos.redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent cbf3d60 commit 69929d4

File tree

3 files changed

+60
-23
lines changed

3 files changed

+60
-23
lines changed

include/uapi/linux/openvswitch.h

+2
Original file line numberDiff line numberDiff line change
@@ -1058,4 +1058,6 @@ enum ovs_dec_ttl_attr {
10581058
__OVS_DEC_TTL_ATTR_MAX
10591059
};
10601060

1061+
#define OVS_DEC_TTL_ATTR_MAX (__OVS_DEC_TTL_ATTR_MAX - 1)
1062+
10611063
#endif /* _LINUX_OPENVSWITCH_H */

net/openvswitch/actions.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -958,14 +958,13 @@ static int dec_ttl_exception_handler(struct datapath *dp, struct sk_buff *skb,
958958
{
959959
/* The first action is always 'OVS_DEC_TTL_ATTR_ARG'. */
960960
struct nlattr *dec_ttl_arg = nla_data(attr);
961-
int rem = nla_len(attr);
962961

963962
if (nla_len(dec_ttl_arg)) {
964-
struct nlattr *actions = nla_next(dec_ttl_arg, &rem);
963+
struct nlattr *actions = nla_data(dec_ttl_arg);
965964

966965
if (actions)
967-
return clone_execute(dp, skb, key, 0, actions, rem,
968-
last, false);
966+
return clone_execute(dp, skb, key, 0, nla_data(actions),
967+
nla_len(actions), last, false);
969968
}
970969
consume_skb(skb);
971970
return 0;

net/openvswitch/flow_netlink.c

+55-19
Original file line numberDiff line numberDiff line change
@@ -2503,28 +2503,42 @@ static int validate_and_copy_dec_ttl(struct net *net,
25032503
__be16 eth_type, __be16 vlan_tci,
25042504
u32 mpls_label_count, bool log)
25052505
{
2506-
int start, err;
2507-
u32 nested = true;
2506+
const struct nlattr *attrs[OVS_DEC_TTL_ATTR_MAX + 1];
2507+
int start, action_start, err, rem;
2508+
const struct nlattr *a, *actions;
2509+
2510+
memset(attrs, 0, sizeof(attrs));
2511+
nla_for_each_nested(a, attr, rem) {
2512+
int type = nla_type(a);
25082513

2509-
if (!nla_len(attr))
2510-
return ovs_nla_add_action(sfa, OVS_ACTION_ATTR_DEC_TTL,
2511-
NULL, 0, log);
2514+
/* Ignore unknown attributes to be future proof. */
2515+
if (type > OVS_DEC_TTL_ATTR_MAX)
2516+
continue;
2517+
2518+
if (!type || attrs[type])
2519+
return -EINVAL;
2520+
2521+
attrs[type] = a;
2522+
}
2523+
2524+
actions = attrs[OVS_DEC_TTL_ATTR_ACTION];
2525+
if (rem || !actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
2526+
return -EINVAL;
25122527

25132528
start = add_nested_action_start(sfa, OVS_ACTION_ATTR_DEC_TTL, log);
25142529
if (start < 0)
25152530
return start;
25162531

2517-
err = ovs_nla_add_action(sfa, OVS_DEC_TTL_ATTR_ACTION, &nested,
2518-
sizeof(nested), log);
2519-
2520-
if (err)
2521-
return err;
2532+
action_start = add_nested_action_start(sfa, OVS_DEC_TTL_ATTR_ACTION, log);
2533+
if (action_start < 0)
2534+
return start;
25222535

2523-
err = __ovs_nla_copy_actions(net, attr, key, sfa, eth_type,
2536+
err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type,
25242537
vlan_tci, mpls_label_count, log);
25252538
if (err)
25262539
return err;
25272540

2541+
add_nested_action_end(*sfa, action_start);
25282542
add_nested_action_end(*sfa, start);
25292543
return 0;
25302544
}
@@ -3487,20 +3501,42 @@ static int check_pkt_len_action_to_attr(const struct nlattr *attr,
34873501
static int dec_ttl_action_to_attr(const struct nlattr *attr,
34883502
struct sk_buff *skb)
34893503
{
3490-
int err = 0, rem = nla_len(attr);
3491-
struct nlattr *start;
3504+
struct nlattr *start, *action_start;
3505+
const struct nlattr *a;
3506+
int err = 0, rem;
34923507

34933508
start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_DEC_TTL);
3494-
34953509
if (!start)
34963510
return -EMSGSIZE;
34973511

3498-
err = ovs_nla_put_actions(nla_data(attr), rem, skb);
3499-
if (err)
3500-
nla_nest_cancel(skb, start);
3501-
else
3502-
nla_nest_end(skb, start);
3512+
nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
3513+
switch (nla_type(a)) {
3514+
case OVS_DEC_TTL_ATTR_ACTION:
3515+
3516+
action_start = nla_nest_start_noflag(skb, OVS_DEC_TTL_ATTR_ACTION);
3517+
if (!action_start) {
3518+
err = -EMSGSIZE;
3519+
goto out;
3520+
}
3521+
3522+
err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
3523+
if (err)
3524+
goto out;
3525+
3526+
nla_nest_end(skb, action_start);
3527+
break;
35033528

3529+
default:
3530+
/* Ignore all other option to be future compatible */
3531+
break;
3532+
}
3533+
}
3534+
3535+
nla_nest_end(skb, start);
3536+
return 0;
3537+
3538+
out:
3539+
nla_nest_cancel(skb, start);
35043540
return err;
35053541
}
35063542

0 commit comments

Comments
 (0)