Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: openvswitch: add last-action drop reason

Create a new drop reason subsystem for openvswitch and add the first
drop reason to represent last-action drops.

Last-action drops happen when a flow has an empty action list or there
is no action that consumes the packet (output, userspace, recirc, etc).
It is the most common way in which OVS drops packets.

Implementation-wise, most of these skb-consuming actions already call
"consume_skb" internally and return directly from within the
do_execute_actions() loop so with minimal changes we can assume that
any skb that exits the loop normally is a packet drop.

Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Adrian Moreno and committed by
David S. Miller
9d802da4 afb0c192

+63 -2
+6
include/net/dropreason.h
··· 23 23 */ 24 24 SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR, 25 25 26 + /** 27 + * @SKB_DROP_REASON_SUBSYS_OPENVSWITCH: openvswitch drop reasons, 28 + * see net/openvswitch/drop.h 29 + */ 30 + SKB_DROP_REASON_SUBSYS_OPENVSWITCH, 31 + 26 32 /** @SKB_DROP_REASON_SUBSYS_NUM: number of subsystems defined */ 27 33 SKB_DROP_REASON_SUBSYS_NUM 28 34 };
+10 -2
net/openvswitch/actions.c
··· 27 27 #include <net/sctp/checksum.h> 28 28 29 29 #include "datapath.h" 30 + #include "drop.h" 30 31 #include "flow.h" 31 32 #include "conntrack.h" 32 33 #include "vport.h" ··· 1037 1036 if ((arg->probability != U32_MAX) && 1038 1037 (!arg->probability || get_random_u32() > arg->probability)) { 1039 1038 if (last) 1040 - consume_skb(skb); 1039 + ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION); 1041 1040 return 0; 1042 1041 } 1043 1042 ··· 1298 1297 if (trace_ovs_do_execute_action_enabled()) 1299 1298 trace_ovs_do_execute_action(dp, skb, key, a, rem); 1300 1299 1300 + /* Actions that rightfully have to consume the skb should do it 1301 + * and return directly. 1302 + */ 1301 1303 switch (nla_type(a)) { 1302 1304 case OVS_ACTION_ATTR_OUTPUT: { 1303 1305 int port = nla_get_u32(a); ··· 1336 1332 output_userspace(dp, skb, key, a, attr, 1337 1333 len, OVS_CB(skb)->cutlen); 1338 1334 OVS_CB(skb)->cutlen = 0; 1335 + if (nla_is_last(a, rem)) { 1336 + consume_skb(skb); 1337 + return 0; 1338 + } 1339 1339 break; 1340 1340 1341 1341 case OVS_ACTION_ATTR_HASH: ··· 1493 1485 } 1494 1486 } 1495 1487 1496 - consume_skb(skb); 1488 + ovs_kfree_skb_reason(skb, OVS_DROP_LAST_ACTION); 1497 1489 return 0; 1498 1490 } 1499 1491
+16
net/openvswitch/datapath.c
··· 41 41 #include <net/pkt_cls.h> 42 42 43 43 #include "datapath.h" 44 + #include "drop.h" 44 45 #include "flow.h" 45 46 #include "flow_table.h" 46 47 #include "flow_netlink.h" ··· 2703 2702 .size = sizeof(struct ovs_net), 2704 2703 }; 2705 2704 2705 + static const char * const ovs_drop_reasons[] = { 2706 + #define S(x) (#x), 2707 + OVS_DROP_REASONS(S) 2708 + #undef S 2709 + }; 2710 + 2711 + static struct drop_reason_list drop_reason_list_ovs = { 2712 + .reasons = ovs_drop_reasons, 2713 + .n_reasons = ARRAY_SIZE(ovs_drop_reasons), 2714 + }; 2715 + 2706 2716 static int __init dp_init(void) 2707 2717 { 2708 2718 int err; ··· 2755 2743 if (err < 0) 2756 2744 goto error_unreg_netdev; 2757 2745 2746 + drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_OPENVSWITCH, 2747 + &drop_reason_list_ovs); 2748 + 2758 2749 return 0; 2759 2750 2760 2751 error_unreg_netdev: ··· 2784 2769 ovs_netdev_exit(); 2785 2770 unregister_netdevice_notifier(&ovs_dp_device_notifier); 2786 2771 unregister_pernet_device(&ovs_net_ops); 2772 + drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_OPENVSWITCH); 2787 2773 rcu_barrier(); 2788 2774 ovs_vport_exit(); 2789 2775 ovs_flow_exit();
+31
net/openvswitch/drop.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * OpenvSwitch drop reason list. 4 + */ 5 + 6 + #ifndef OPENVSWITCH_DROP_H 7 + #define OPENVSWITCH_DROP_H 8 + #include <linux/skbuff.h> 9 + #include <net/dropreason.h> 10 + 11 + #define OVS_DROP_REASONS(R) \ 12 + R(OVS_DROP_LAST_ACTION) \ 13 + /* deliberate comment for trailing \ */ 14 + 15 + enum ovs_drop_reason { 16 + __OVS_DROP_REASON = SKB_DROP_REASON_SUBSYS_OPENVSWITCH << 17 + SKB_DROP_REASON_SUBSYS_SHIFT, 18 + #define ENUM(x) x, 19 + OVS_DROP_REASONS(ENUM) 20 + #undef ENUM 21 + 22 + OVS_DROP_MAX, 23 + }; 24 + 25 + static inline void 26 + ovs_kfree_skb_reason(struct sk_buff *skb, enum ovs_drop_reason reason) 27 + { 28 + kfree_skb_reason(skb, (u32)reason); 29 + } 30 + 31 + #endif /* OPENVSWITCH_DROP_H */