Skip to content

Commit 9b52e3f

Browse files
fomichevborkmann
authored andcommitted
flow_dissector: handle no-skb use case
When called without skb, gather all required data from the __skb_flow_dissect's arguments and use recently introduces no-skb mode of bpf flow dissector. Note: WARN_ON_ONCE(!net) will now trigger for eth_get_headlen users. Signed-off-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 3cbf4ff commit 9b52e3f

File tree

2 files changed

+25
-32
lines changed

2 files changed

+25
-32
lines changed

include/linux/skbuff.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,11 +1279,6 @@ struct bpf_flow_dissector;
12791279
bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
12801280
__be16 proto, int nhoff, int hlen);
12811281

1282-
struct bpf_flow_keys;
1283-
bool __skb_flow_bpf_dissect(struct bpf_prog *prog,
1284-
const struct sk_buff *skb,
1285-
struct flow_dissector *flow_dissector,
1286-
struct bpf_flow_keys *flow_keys);
12871282
bool __skb_flow_dissect(const struct net *net,
12881283
const struct sk_buff *skb,
12891284
struct flow_dissector *flow_dissector,

net/core/flow_dissector.c

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -683,22 +683,6 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
683683
}
684684
}
685685

686-
bool __skb_flow_bpf_dissect(struct bpf_prog *prog,
687-
const struct sk_buff *skb,
688-
struct flow_dissector *flow_dissector,
689-
struct bpf_flow_keys *flow_keys)
690-
{
691-
struct bpf_flow_dissector ctx = {
692-
.flow_keys = flow_keys,
693-
.skb = skb,
694-
.data = skb->data,
695-
.data_end = skb->data + skb_headlen(skb),
696-
};
697-
698-
return bpf_flow_dissect(prog, &ctx, skb->protocol,
699-
skb_network_offset(skb), skb_headlen(skb));
700-
}
701-
702686
bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
703687
__be16 proto, int nhoff, int hlen)
704688
{
@@ -753,6 +737,7 @@ bool __skb_flow_dissect(const struct net *net,
753737
struct flow_dissector_key_icmp *key_icmp;
754738
struct flow_dissector_key_tags *key_tags;
755739
struct flow_dissector_key_vlan *key_vlan;
740+
struct bpf_prog *attached = NULL;
756741
enum flow_dissect_ret fdret;
757742
enum flow_dissector_key_id dissector_vlan = FLOW_DISSECTOR_KEY_MAX;
758743
int num_hdrs = 0;
@@ -795,26 +780,39 @@ bool __skb_flow_dissect(const struct net *net,
795780
target_container);
796781

797782
if (skb) {
798-
struct bpf_flow_keys flow_keys;
799-
struct bpf_prog *attached = NULL;
800-
801-
rcu_read_lock();
802783
if (!net) {
803784
if (skb->dev)
804785
net = dev_net(skb->dev);
805786
else if (skb->sk)
806787
net = sock_net(skb->sk);
807-
else
808-
WARN_ON_ONCE(1);
809788
}
789+
}
810790

811-
if (net)
812-
attached = rcu_dereference(net->flow_dissector_prog);
791+
WARN_ON_ONCE(!net);
792+
if (net) {
793+
rcu_read_lock();
794+
attached = rcu_dereference(net->flow_dissector_prog);
813795

814796
if (attached) {
815-
ret = __skb_flow_bpf_dissect(attached, skb,
816-
flow_dissector,
817-
&flow_keys);
797+
struct bpf_flow_keys flow_keys;
798+
struct bpf_flow_dissector ctx = {
799+
.flow_keys = &flow_keys,
800+
.data = data,
801+
.data_end = data + hlen,
802+
};
803+
__be16 n_proto = proto;
804+
805+
if (skb) {
806+
ctx.skb = skb;
807+
/* we can't use 'proto' in the skb case
808+
* because it might be set to skb->vlan_proto
809+
* which has been pulled from the data
810+
*/
811+
n_proto = skb->protocol;
812+
}
813+
814+
ret = bpf_flow_dissect(attached, &ctx, n_proto, nhoff,
815+
hlen);
818816
__skb_flow_bpf_to_target(&flow_keys, flow_dissector,
819817
target_container);
820818
rcu_read_unlock();

0 commit comments

Comments
 (0)