Skip to content

Commit d2675fe

Browse files
committed
Merge branch 'net-flow-dissector-allow-explicit-passing-of-netns'
Florian Westphal says: ==================== net: flow dissector: allow explicit passing of netns Change since last version: fix kdoc comment warning reported by kbuild robot, no other changes, thus retaining RvB tags from Eric and Willem. v1: https://lore.kernel.org/netdev/[email protected]/ Years ago flow dissector gained ability to delegate flow dissection to a bpf program, scoped per netns. The netns is derived from skb->dev, and if that is not available, from skb->sk. If neither is set, we hit a (benign) WARN_ON_ONCE(). This WARN_ON_ONCE can be triggered from netfilter. Known skb origins are nf_send_reset and ipv4 stack generated IGMP messages. Lets allow callers to pass the current netns explicitly and make nf_tables use those instead. This targets net-next instead of net because the WARN is benign and this is not a regression. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 91579c9 + d1dab4f commit d2675fe

File tree

4 files changed

+34
-12
lines changed

4 files changed

+34
-12
lines changed

include/linux/skbuff.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,8 +1498,14 @@ __skb_set_sw_hash(struct sk_buff *skb, __u32 hash, bool is_l4)
14981498
__skb_set_hash(skb, hash, true, is_l4);
14991499
}
15001500

1501-
void __skb_get_hash(struct sk_buff *skb);
1502-
u32 __skb_get_hash_symmetric(const struct sk_buff *skb);
1501+
u32 __skb_get_hash_symmetric_net(const struct net *net, const struct sk_buff *skb);
1502+
1503+
static inline u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
1504+
{
1505+
return __skb_get_hash_symmetric_net(NULL, skb);
1506+
}
1507+
1508+
void __skb_get_hash_net(const struct net *net, struct sk_buff *skb);
15031509
u32 skb_get_poff(const struct sk_buff *skb);
15041510
u32 __skb_get_poff(const struct sk_buff *skb, const void *data,
15051511
const struct flow_keys_basic *keys, int hlen);
@@ -1578,10 +1584,18 @@ void skb_flow_dissect_hash(const struct sk_buff *skb,
15781584
struct flow_dissector *flow_dissector,
15791585
void *target_container);
15801586

1587+
static inline __u32 skb_get_hash_net(const struct net *net, struct sk_buff *skb)
1588+
{
1589+
if (!skb->l4_hash && !skb->sw_hash)
1590+
__skb_get_hash_net(net, skb);
1591+
1592+
return skb->hash;
1593+
}
1594+
15811595
static inline __u32 skb_get_hash(struct sk_buff *skb)
15821596
{
15831597
if (!skb->l4_hash && !skb->sw_hash)
1584-
__skb_get_hash(skb);
1598+
__skb_get_hash_net(NULL, skb);
15851599

15861600
return skb->hash;
15871601
}

net/core/flow_dissector.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,41 +1845,48 @@ EXPORT_SYMBOL(make_flow_keys_digest);
18451845

18461846
static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;
18471847

1848-
u32 __skb_get_hash_symmetric(const struct sk_buff *skb)
1848+
u32 __skb_get_hash_symmetric_net(const struct net *net, const struct sk_buff *skb)
18491849
{
18501850
struct flow_keys keys;
18511851

18521852
__flow_hash_secret_init();
18531853

18541854
memset(&keys, 0, sizeof(keys));
1855-
__skb_flow_dissect(NULL, skb, &flow_keys_dissector_symmetric,
1855+
__skb_flow_dissect(net, skb, &flow_keys_dissector_symmetric,
18561856
&keys, NULL, 0, 0, 0, 0);
18571857

18581858
return __flow_hash_from_keys(&keys, &hashrnd);
18591859
}
1860-
EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
1860+
EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric_net);
18611861

18621862
/**
1863-
* __skb_get_hash: calculate a flow hash
1863+
* __skb_get_hash_net: calculate a flow hash
1864+
* @net: associated network namespace, derived from @skb if NULL
18641865
* @skb: sk_buff to calculate flow hash from
18651866
*
18661867
* This function calculates a flow hash based on src/dst addresses
18671868
* and src/dst port numbers. Sets hash in skb to non-zero hash value
18681869
* on success, zero indicates no valid hash. Also, sets l4_hash in skb
18691870
* if hash is a canonical 4-tuple hash over transport ports.
18701871
*/
1871-
void __skb_get_hash(struct sk_buff *skb)
1872+
void __skb_get_hash_net(const struct net *net, struct sk_buff *skb)
18721873
{
18731874
struct flow_keys keys;
18741875
u32 hash;
18751876

1877+
memset(&keys, 0, sizeof(keys));
1878+
1879+
__skb_flow_dissect(net, skb, &flow_keys_dissector,
1880+
&keys, NULL, 0, 0, 0,
1881+
FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
1882+
18761883
__flow_hash_secret_init();
18771884

1878-
hash = ___skb_get_hash(skb, &keys, &hashrnd);
1885+
hash = __flow_hash_from_keys(&keys, &hashrnd);
18791886

18801887
__skb_set_sw_hash(skb, hash, flow_keys_have_l4(&keys));
18811888
}
1882-
EXPORT_SYMBOL(__skb_get_hash);
1889+
EXPORT_SYMBOL(__skb_get_hash_net);
18831890

18841891
__u32 skb_get_hash_perturb(const struct sk_buff *skb,
18851892
const siphash_key_t *perturb)

net/netfilter/nf_tables_trace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ void nft_trace_init(struct nft_traceinfo *info, const struct nft_pktinfo *pkt,
317317
net_get_random_once(&trace_key, sizeof(trace_key));
318318

319319
info->skbid = (u32)siphash_3u32(hash32_ptr(skb),
320-
skb_get_hash(skb),
320+
skb_get_hash_net(nft_net(pkt), skb),
321321
skb->skb_iif,
322322
&trace_key);
323323
}

net/netfilter/nft_hash.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ static void nft_symhash_eval(const struct nft_expr *expr,
5151
struct sk_buff *skb = pkt->skb;
5252
u32 h;
5353

54-
h = reciprocal_scale(__skb_get_hash_symmetric(skb), priv->modulus);
54+
h = reciprocal_scale(__skb_get_hash_symmetric_net(nft_net(pkt), skb),
55+
priv->modulus);
5556

5657
regs->data[priv->dreg] = h + priv->offset;
5758
}

0 commit comments

Comments
 (0)