Skip to content

Commit 876c273

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nf_conntrack_sip: allow duplicate SDP expectations
Callum Sinclair reported SIP IP Phone errors that he tracked down to such phones sending session descriptions for different media types but with same port numbers. The expect core will only 'refresh' existing expectation if it is from same master AND same expectation class (media type). As expectation class is different, we get an error. The SIP connection tracking code will then 1). drop the SDP packet 2). if an rtp expectation was already installed successfully, error on rtcp expectation will cancel the rtp one. Make the expect core report back to caller when the conflict is due to different expectation class and have SIP tracker ignore soft-error. Reported-by: Callum Sinclair <[email protected]> Tested-by: Callum Sinclair <[email protected]> Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent a2ac999 commit 876c273

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

net/netfilter/nf_conntrack_expect.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
252252
static inline int expect_matches(const struct nf_conntrack_expect *a,
253253
const struct nf_conntrack_expect *b)
254254
{
255-
return a->master == b->master && a->class == b->class &&
255+
return a->master == b->master &&
256256
nf_ct_tuple_equal(&a->tuple, &b->tuple) &&
257257
nf_ct_tuple_mask_equal(&a->mask, &b->mask) &&
258258
net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) &&
@@ -421,6 +421,9 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect)
421421
h = nf_ct_expect_dst_hash(net, &expect->tuple);
422422
hlist_for_each_entry_safe(i, next, &nf_ct_expect_hash[h], hnode) {
423423
if (expect_matches(i, expect)) {
424+
if (i->class != expect->class)
425+
return -EALREADY;
426+
424427
if (nf_ct_remove_expect(i))
425428
break;
426429
} else if (expect_clash(i, expect)) {

net/netfilter/nf_conntrack_sip.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -938,11 +938,19 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
938938
datalen, rtp_exp, rtcp_exp,
939939
mediaoff, medialen, daddr);
940940
else {
941-
if (nf_ct_expect_related(rtp_exp) == 0) {
942-
if (nf_ct_expect_related(rtcp_exp) != 0)
943-
nf_ct_unexpect_related(rtp_exp);
944-
else
941+
/* -EALREADY handling works around end-points that send
942+
* SDP messages with identical port but different media type,
943+
* we pretend expectation was set up.
944+
*/
945+
int errp = nf_ct_expect_related(rtp_exp);
946+
947+
if (errp == 0 || errp == -EALREADY) {
948+
int errcp = nf_ct_expect_related(rtcp_exp);
949+
950+
if (errcp == 0 || errcp == -EALREADY)
945951
ret = NF_ACCEPT;
952+
else if (errp == 0)
953+
nf_ct_unexpect_related(rtp_exp);
946954
}
947955
}
948956
nf_ct_expect_put(rtcp_exp);

0 commit comments

Comments
 (0)