mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 14:25:26 +00:00
Add a new OVS action check_pkt_larger
This patch adds a new action 'check_pkt_larger' which checks if the
packet is larger than the given size and stores the result in the
destination register.
Usage: check_pkt_larger(len)->REGISTER
Eg. match=...,actions=check_pkt_larger(1442)->NXM_NX_REG0[0],next;
This patch makes use of the new datapath action - 'check_pkt_len'
which was recently added in the commit [1].
At the start of ovs-vswitchd, datapath is probed for this action.
If the datapath action is present, then 'check_pkt_larger'
makes use of this datapath action.
Datapath action 'check_pkt_len' takes these nlattrs
* OVS_CHECK_PKT_LEN_ATTR_PKT_LEN - 'pkt_len' to check for
* OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER (optional) - Nested actions
to apply if the packet length is greater than the specified 'pkt_len'
* OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL (optional) - Nested
actions to apply if the packet length is lesser or equal to the
specified 'pkt_len'.
Let's say we have these flows added to an OVS bridge br-int
table=0, priority=100 in_port=1,ip,actions=check_pkt_larger:100->NXM_NX_REG0[0],resubmit(,1)
table=1, priority=200,in_port=1,ip,reg0=0x1/0x1 actions=output:3
table=1, priority=100,in_port=1,ip,actions=output:4
Then the action 'check_pkt_larger' will be translated as
- check_pkt_len(size=100,gt(3),le(4))
datapath will check the packet length and if the packet length is greater than 100,
it will output to port 3, else it will output to port 4.
In case, datapath doesn't support 'check_pkt_len' action, the OVS action
'check_pkt_larger' sets SLOW_ACTION so that datapath flow is not added.
This OVS action is intended to be used by OVN to check the packet length
and generate an ICMP packet with type 3, code 4 and next hop mtu
in the logical router pipeline if the MTU of the physical interface
is lesser than the packet length. More information can be found here [2]
[1] - 4d5ec89fc8
[2] - https://mail.openvswitch.org/pipermail/ovs-discuss/2018-July/047039.html
Reported-at:
https://mail.openvswitch.org/pipermail/ovs-discuss/2018-July/047039.html
Suggested-by: Ben Pfaff <blp@ovn.org>
Signed-off-by: Numan Siddique <nusiddiq@redhat.com>
CC: Ben Pfaff <blp@ovn.org>
CC: Gregory Rose <gvrose8192@gmail.com>
Acked-by: Mark Michelson <mmichels@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
committed by
Ben Pfaff
parent
718be50dae
commit
5b34f8fc3b
@@ -674,6 +674,49 @@ odp_execute_clone(void *dp, struct dp_packet_batch *batch, bool steal,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
odp_execute_check_pkt_len(void *dp, struct dp_packet *packet, bool steal,
|
||||
const struct nlattr *action,
|
||||
odp_execute_cb dp_execute_action)
|
||||
{
|
||||
static const struct nl_policy ovs_cpl_policy[] = {
|
||||
[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] = { .type = NL_A_U16 },
|
||||
[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER] = { .type = NL_A_NESTED },
|
||||
[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL]
|
||||
= { .type = NL_A_NESTED },
|
||||
};
|
||||
struct nlattr *attrs[ARRAY_SIZE(ovs_cpl_policy)];
|
||||
|
||||
if (!nl_parse_nested(action, ovs_cpl_policy, attrs, ARRAY_SIZE(attrs))) {
|
||||
OVS_NOT_REACHED();
|
||||
}
|
||||
|
||||
const struct nlattr *a;
|
||||
struct dp_packet_batch pb;
|
||||
|
||||
a = attrs[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN];
|
||||
bool is_greater = dp_packet_size(packet) > nl_attr_get_u16(a);
|
||||
if (is_greater) {
|
||||
a = attrs[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER];
|
||||
} else {
|
||||
a = attrs[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL];
|
||||
}
|
||||
|
||||
if (!steal) {
|
||||
/* The 'subactions' may modify the packet, but the modification
|
||||
* should not propagate beyond this action. Make a copy
|
||||
* the packet in case we don't own the packet, so that the
|
||||
* 'subactions' are only applid to check_pkt_len. 'odp_execute_actions'
|
||||
* will free the clone. */
|
||||
packet = dp_packet_clone(packet);
|
||||
}
|
||||
/* If nl_attr_get(a) is NULL, the packet will be freed by
|
||||
* odp_execute_actions. */
|
||||
dp_packet_batch_init_packet(&pb, packet);
|
||||
odp_execute_actions(dp, &pb, true, nl_attr_get(a), nl_attr_get_size(a),
|
||||
dp_execute_action);
|
||||
}
|
||||
|
||||
static bool
|
||||
requires_datapath_assistance(const struct nlattr *a)
|
||||
{
|
||||
@@ -705,6 +748,7 @@ requires_datapath_assistance(const struct nlattr *a)
|
||||
case OVS_ACTION_ATTR_PUSH_NSH:
|
||||
case OVS_ACTION_ATTR_POP_NSH:
|
||||
case OVS_ACTION_ATTR_CT_CLEAR:
|
||||
case OVS_ACTION_ATTR_CHECK_PKT_LEN:
|
||||
return false;
|
||||
|
||||
case OVS_ACTION_ATTR_UNSPEC:
|
||||
@@ -932,6 +976,19 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
|
||||
}
|
||||
break;
|
||||
|
||||
case OVS_ACTION_ATTR_CHECK_PKT_LEN:
|
||||
DP_PACKET_BATCH_FOR_EACH (i, packet, batch) {
|
||||
odp_execute_check_pkt_len(dp, packet, steal && last_action, a,
|
||||
dp_execute_action);
|
||||
}
|
||||
|
||||
if (last_action) {
|
||||
/* We do not need to free the packets.
|
||||
* odp_execute_check_pkt_len() has stolen them. */
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case OVS_ACTION_ATTR_OUTPUT:
|
||||
case OVS_ACTION_ATTR_TUNNEL_PUSH:
|
||||
case OVS_ACTION_ATTR_TUNNEL_POP:
|
||||
|
Reference in New Issue
Block a user