MT#55283 handle non-linear skbuffs

Convert skb to linear by making a copy if it isn't already, so that all
data can be easily accessed.

Change-Id: Iea4005ac0e650fea3c20eebe0da251d839dda7b5
master
Richard Fuchs 3 days ago
parent fda6cbf8b1
commit cb2ce35789

@ -6636,6 +6636,9 @@ static struct sk_buff *rtpe_skb_cpy(const struct sk_buff *oskb, const struct rtp
atomic64_inc(&t->skb_copies);
if (!rtp)
return skb;
// adjust RTP pointers
*rtp2 = *rtp;
offset = skb->data - oskb->data;
@ -7152,8 +7155,6 @@ static int rtpengine46(struct sk_buff *oskb,
datalen -= sizeof(*uh);
DBG("udp payload = %u\n", datalen);
data = ((unsigned char *) uh) + sizeof(*uh);
// all our outputs filled?
_r_lock(&g->outputs_lock, flags);
if (g->outputs_unfilled) {
@ -7163,6 +7164,17 @@ static int rtpengine46(struct sk_buff *oskb,
}
_r_unlock(&g->outputs_lock, flags);
// prepare to access payload of packet. make sure it's a flat buffer
// XXX could be smarter about this, we usually just need the header
if (skb_needs_linearize(oskb, 0)) {
skb = rtpe_skb_cpy(oskb, NULL, NULL, t);
if (!skb)
goto out_error;
uh = udp_hdr(skb);
}
data = ((unsigned char *) uh) + sizeof(*uh);
if (is_stun(g, datalen, data))
goto out_target;
@ -7238,7 +7250,7 @@ static int rtpengine46(struct sk_buff *oskb,
g->target.ssrc_stats);
// copy to decrypt/authenticate needed?
if (g->target.decrypt.hmac != REH_NULL || g->decrypt_rtp.cipher->decrypt_rtp) {
if (!skb && (g->target.decrypt.hmac != REH_NULL || g->decrypt_rtp.cipher->decrypt_rtp)) {
errstr = "out of memory";
skb = rtpe_skb_cpy(oskb, &rtp, &rtp, t);
if (!skb)
@ -7303,10 +7315,12 @@ static int rtpengine46(struct sk_buff *oskb,
// 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, t);
if (!skb)
goto out_error;
if (!skb) {
errstr = "out of memory";
skb = rtpe_skb_cpy(oskb, &rtp, &rtp, t);
if (!skb)
goto out_error;
}
rtpe_pull_trim(skb, datalen);
@ -7330,8 +7344,10 @@ static int rtpengine46(struct sk_buff *oskb,
}
else {
// forward non-RTP/RTCP. no copy needed
skb = skb_get(oskb);
atomic64_inc(&t->skb_refs);
if (!skb) {
skb = skb_get(oskb);
atomic64_inc(&t->skb_refs);
}
nf_action = NF_DROP;
rtpe_pull_trim(skb, datalen);

Loading…
Cancel
Save