MT#55283 make skb copies on demand

Reuse the existing skb whenever possible for normal forwarding. Make a
copy only when needed: when decrypying or encrypting, or when there's
not enough space.

Change-Id: Ia3b020e65dcfcf0c4a63502607431144af44b1f4
pull/2149/head
Richard Fuchs 4 weeks ago
parent df8cb30a84
commit 8dd97e20a6

@ -5439,6 +5439,14 @@ static int send_proxy_packet4(struct sk_buff *skb, const struct re_address *src,
datalen = skb->len;
if (skb_headroom(skb) < sizeof(*uh) + sizeof(*ih)) {
struct sk_buff *skb2 = skb_copy_expand(skb, MAX_HEADER, MAX_SKB_TAIL_ROOM, GFP_ATOMIC);
if (!skb2)
goto drop;
kfree_skb(skb);
skb = skb2;
}
uh = (void *) skb_push(skb, sizeof(*uh));
skb_reset_transport_header(skb);
ih = (void *) skb_push(skb, sizeof(*ih));
@ -5547,6 +5555,14 @@ static int send_proxy_packet6(struct sk_buff *skb, const struct re_address *src,
datalen = skb->len;
if (skb_headroom(skb) < sizeof(*uh) + sizeof(*ih)) {
struct sk_buff *skb2 = skb_copy_expand(skb, MAX_HEADER, MAX_SKB_TAIL_ROOM, GFP_ATOMIC);
if (!skb2)
goto drop;
kfree_skb(skb);
skb = skb2;
}
uh = (void *) skb_push(skb, sizeof(*uh));
skb_reset_transport_header(skb);
ih = (void *) skb_push(skb, sizeof(*ih));
@ -6672,6 +6688,15 @@ static struct sk_buff *proxy_packet_output_rtXp(struct sk_buff *skb, struct rtpe
rtp->rtp_header->ssrc = o->output.ssrc_out[ssrc_idx];
}
// copy to encrypt/authenticate needed?
if (o->output.encrypt.hmac != REH_NULL || o->encrypt_rtp.cipher->encrypt_rtp) {
struct sk_buff *skb2 = rtpe_skb_cpy(skb, rtp, rtp);
if (!skb2)
goto drop;
kfree_skb(skb);
skb = skb2;
}
pkt_idx = proxy_packet_srtp_encrypt(skb, &o->encrypt_rtp, &o->output.encrypt,
rtp, ssrc_idx, o->output.ssrc_stats);
@ -7136,13 +7161,6 @@ static int rtpengine46(struct sk_buff *oskb,
}
}
skb = rtpe_skb_cpy(oskb, &rtp, &rtp);
if (!skb)
goto out_target;
rtpe_pull_trim(skb, datalen);
data = skb->data;
if (rtp.ok) {
// RTP ok
rtp_pt_idx = rtp_payload_type(rtp.rtp_header, &g->target, &g->last_pt);
@ -7161,6 +7179,15 @@ static int rtpengine46(struct sk_buff *oskb,
pkt_idx = rtp_packet_index(&g->decrypt_rtp, &g->target.decrypt, rtp.rtp_header, ssrc_idx,
g->target.ssrc_stats);
// copy to decrypt/authenticate needed?
if (g->target.decrypt.hmac != REH_NULL || g->decrypt_rtp.cipher->decrypt_rtp) {
errstr = "out of memory";
skb = rtpe_skb_cpy(oskb, &rtp, &rtp);
if (!skb)
goto out_error;
}
errstr = "SRTP authentication tag mismatch";
if (srtp_auth_validate(&g->decrypt_rtp, &g->target.decrypt, &rtp, &pkt_idx, ssrc_idx,
g->target.ssrc_stats))
@ -7186,6 +7213,16 @@ static int rtpengine46(struct sk_buff *oskb,
err = srtp_decrypt(&g->decrypt_rtp, &g->target.decrypt, &rtp, &pkt_idx);
if (err < 0)
goto out_error;
// everything passed, we will definitely handle this packet
nf_action = NF_DROP;
// if we haven't made a copy yet, we can use the original skb directly
if (!skb)
skb = skb_get(oskb);
rtpe_pull_trim(skb, datalen);
if (err == 1)
update_packet_index(&g->decrypt_rtp, &g->target.decrypt, pkt_idx, ssrc_idx,
g->target.ssrc_stats);
@ -7201,11 +7238,19 @@ static int rtpengine46(struct sk_buff *oskb,
rtp.payload[8], rtp.payload[9], rtp.payload[10], rtp.payload[11],
rtp.payload[12], rtp.payload[13], rtp.payload[14], rtp.payload[15],
rtp.payload[16], rtp.payload[17], rtp.payload[18], rtp.payload[19]);
nf_action = NF_DROP;
}
else if (is_rtcp != NOT_RTCP && rtp.rtcp) {
pkt_idx = 0;
// always make a copy for RTCP
// (even if technically not needed for NF_DROP case below)
errstr = "out of memory";
skb = rtpe_skb_cpy(oskb, &rtp, &rtp);
if (!skb)
goto out_error;
rtpe_pull_trim(skb, datalen);
err = srtcp_auth_validate(&g->decrypt_rtcp, &g->target.decrypt, &rtp, &pkt_idx);
errstr = "SRTCP authentication tag mismatch";
if (err == -1)
@ -7224,9 +7269,14 @@ static int rtpengine46(struct sk_buff *oskb,
else
nf_action = NF_DROP;
}
else
else {
// forward non-RTP/RTCP. no copy needed
skb = skb_get(oskb);
nf_action = NF_DROP;
rtpe_pull_trim(skb, datalen);
}
if (g->target.do_intercept) {
DBG("do_intercept is set\n");
stream = get_stream_lock(NULL, g->target.intercept_stream_idx);

Loading…
Cancel
Save