Skip to content

Commit 623e43c

Browse files
rrendeckuba-moo
authored andcommitted
net: bridge: add skb drop reasons to the most common drop points
The bridge input code may drop frames for various reasons and at various points in the ingress handling logic. Currently kfree_skb() is used everywhere, and therefore no drop reason is specified. Add drop reasons to the most common drop points. Drop reasons are not added exhaustively to the entire bridge code. The intention is to incrementally add drop reasons to the rest of the bridge code in follow up patches. Signed-off-by: Radu Rendec <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Acked-by: Nikolay Aleksandrov <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 46e0ccf commit 623e43c

File tree

3 files changed

+39
-9
lines changed

3 files changed

+39
-9
lines changed

include/net/dropreason-core.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@
111111
FN(TUNNEL_TXINFO) \
112112
FN(LOCAL_MAC) \
113113
FN(ARP_PVLAN_DISABLE) \
114+
FN(MAC_IEEE_MAC_CONTROL) \
115+
FN(BRIDGE_INGRESS_STP_STATE) \
114116
FNe(MAX)
115117

116118
/**
@@ -520,6 +522,16 @@ enum skb_drop_reason {
520522
* enabled.
521523
*/
522524
SKB_DROP_REASON_ARP_PVLAN_DISABLE,
525+
/**
526+
* @SKB_DROP_REASON_MAC_IEEE_MAC_CONTROL: the destination MAC address
527+
* is an IEEE MAC Control address.
528+
*/
529+
SKB_DROP_REASON_MAC_IEEE_MAC_CONTROL,
530+
/**
531+
* @SKB_DROP_REASON_BRIDGE_INGRESS_STP_STATE: the STP state of the
532+
* ingress bridge port does not allow frames to be forwarded.
533+
*/
534+
SKB_DROP_REASON_BRIDGE_INGRESS_STP_STATE,
523535
/**
524536
* @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
525537
* shouldn't be used as a real 'reason' - only for tracing code gen

net/bridge/br_forward.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb,
201201
enum br_pkt_type pkt_type, bool local_rcv, bool local_orig,
202202
u16 vid)
203203
{
204+
enum skb_drop_reason reason = SKB_DROP_REASON_NO_TX_TARGET;
204205
struct net_bridge_port *prev = NULL;
205206
struct net_bridge_port *p;
206207

@@ -234,8 +235,11 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb,
234235
continue;
235236

236237
prev = maybe_deliver(prev, p, skb, local_orig);
237-
if (IS_ERR(prev))
238+
if (IS_ERR(prev)) {
239+
reason = PTR_ERR(prev) == -ENOMEM ? SKB_DROP_REASON_NOMEM :
240+
SKB_DROP_REASON_NOT_SPECIFIED;
238241
goto out;
242+
}
239243
}
240244

241245
if (!prev)
@@ -249,7 +253,7 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb,
249253

250254
out:
251255
if (!local_rcv)
252-
kfree_skb(skb);
256+
kfree_skb_reason(skb, reason);
253257
}
254258

255259
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
@@ -289,6 +293,7 @@ void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
289293
struct net_bridge_mcast *brmctx,
290294
bool local_rcv, bool local_orig)
291295
{
296+
enum skb_drop_reason reason = SKB_DROP_REASON_NO_TX_TARGET;
292297
struct net_bridge_port *prev = NULL;
293298
struct net_bridge_port_group *p;
294299
bool allow_mode_include = true;
@@ -329,8 +334,11 @@ void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
329334
}
330335

331336
prev = maybe_deliver(prev, port, skb, local_orig);
332-
if (IS_ERR(prev))
337+
if (IS_ERR(prev)) {
338+
reason = PTR_ERR(prev) == -ENOMEM ? SKB_DROP_REASON_NOMEM :
339+
SKB_DROP_REASON_NOT_SPECIFIED;
333340
goto out;
341+
}
334342
delivered:
335343
if ((unsigned long)lport >= (unsigned long)port)
336344
p = rcu_dereference(p->next);
@@ -349,6 +357,6 @@ void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
349357

350358
out:
351359
if (!local_rcv)
352-
kfree_skb(skb);
360+
kfree_skb_reason(skb, reason);
353361
}
354362
#endif

net/bridge/br_input.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ static int br_pass_frame_up(struct sk_buff *skb, bool promisc)
7575
/* note: already called with rcu_read_lock */
7676
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
7777
{
78+
enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
7879
struct net_bridge_port *p = br_port_get_rcu(skb->dev);
7980
enum br_pkt_type pkt_type = BR_PKT_UNICAST;
8081
struct net_bridge_fdb_entry *dst = NULL;
@@ -96,8 +97,10 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
9697
if (br_mst_is_enabled(br)) {
9798
state = BR_STATE_FORWARDING;
9899
} else {
99-
if (p->state == BR_STATE_DISABLED)
100+
if (p->state == BR_STATE_DISABLED) {
101+
reason = SKB_DROP_REASON_BRIDGE_INGRESS_STP_STATE;
100102
goto drop;
103+
}
101104

102105
state = p->state;
103106
}
@@ -155,8 +158,10 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
155158
}
156159
}
157160

158-
if (state == BR_STATE_LEARNING)
161+
if (state == BR_STATE_LEARNING) {
162+
reason = SKB_DROP_REASON_BRIDGE_INGRESS_STP_STATE;
159163
goto drop;
164+
}
160165

161166
BR_INPUT_SKB_CB(skb)->brdev = br->dev;
162167
BR_INPUT_SKB_CB(skb)->src_port_isolated = !!(p->flags & BR_ISOLATED);
@@ -223,7 +228,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
223228
out:
224229
return 0;
225230
drop:
226-
kfree_skb(skb);
231+
kfree_skb_reason(skb, reason);
227232
goto out;
228233
}
229234
EXPORT_SYMBOL_GPL(br_handle_frame_finish);
@@ -324,15 +329,18 @@ static int br_process_frame_type(struct net_bridge_port *p,
324329
*/
325330
static rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
326331
{
332+
enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED;
327333
struct net_bridge_port *p;
328334
struct sk_buff *skb = *pskb;
329335
const unsigned char *dest = eth_hdr(skb)->h_dest;
330336

331337
if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
332338
return RX_HANDLER_PASS;
333339

334-
if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
340+
if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) {
341+
reason = SKB_DROP_REASON_MAC_INVALID_SOURCE;
335342
goto drop;
343+
}
336344

337345
skb = skb_share_check(skb, GFP_ATOMIC);
338346
if (!skb)
@@ -374,6 +382,7 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
374382
return RX_HANDLER_PASS;
375383

376384
case 0x01: /* IEEE MAC (Pause) */
385+
reason = SKB_DROP_REASON_MAC_IEEE_MAC_CONTROL;
377386
goto drop;
378387

379388
case 0x0E: /* 802.1AB LLDP */
@@ -423,8 +432,9 @@ static rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
423432

424433
return nf_hook_bridge_pre(skb, pskb);
425434
default:
435+
reason = SKB_DROP_REASON_BRIDGE_INGRESS_STP_STATE;
426436
drop:
427-
kfree_skb(skb);
437+
kfree_skb_reason(skb, reason);
428438
}
429439
return RX_HANDLER_CONSUMED;
430440
}

0 commit comments

Comments
 (0)