aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-03-25 23:24:04 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-25 23:24:04 -0400
commit9467ee380ae881443bc259fbbac9992baf523e2d (patch)
tree29fc53175dc0e5b244c27e1a9374c17cd611ca64
parent595a8ecb5fa41295a7010678b60cb2f7ab15fe42 (diff)
[NETFILTER]: nf_conntrack_sip: flush expectations on call termination
Flush the RTP expectations we've created when a call is hung up or terminated otherwise. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/netfilter/nf_conntrack_sip.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 71f744ad7653..8e7e5b465ffb 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -17,6 +17,7 @@
17#include <linux/netfilter.h> 17#include <linux/netfilter.h>
18 18
19#include <net/netfilter/nf_conntrack.h> 19#include <net/netfilter/nf_conntrack.h>
20#include <net/netfilter/nf_conntrack_core.h>
20#include <net/netfilter/nf_conntrack_expect.h> 21#include <net/netfilter/nf_conntrack_expect.h>
21#include <net/netfilter/nf_conntrack_helper.h> 22#include <net/netfilter/nf_conntrack_helper.h>
22#include <linux/netfilter/nf_conntrack_sip.h> 23#include <linux/netfilter/nf_conntrack_sip.h>
@@ -533,6 +534,22 @@ int ct_sip_get_sdp_header(const struct nf_conn *ct, const char *dptr,
533} 534}
534EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header); 535EXPORT_SYMBOL_GPL(ct_sip_get_sdp_header);
535 536
537static void flush_expectations(struct nf_conn *ct)
538{
539 struct nf_conn_help *help = nfct_help(ct);
540 struct nf_conntrack_expect *exp;
541 struct hlist_node *n, *next;
542
543 spin_lock_bh(&nf_conntrack_lock);
544 hlist_for_each_entry_safe(exp, n, next, &help->expectations, lnode) {
545 if (!del_timer(&exp->timeout))
546 continue;
547 nf_ct_unlink_expect(exp);
548 nf_ct_expect_put(exp);
549 }
550 spin_unlock_bh(&nf_conntrack_lock);
551}
552
536static int set_expected_rtp(struct sk_buff *skb, 553static int set_expected_rtp(struct sk_buff *skb,
537 const char **dptr, unsigned int *datalen, 554 const char **dptr, unsigned int *datalen,
538 union nf_inet_addr *addr, __be16 port) 555 union nf_inet_addr *addr, __be16 port)
@@ -606,32 +623,58 @@ static int process_invite_response(struct sk_buff *skb,
606 const char **dptr, unsigned int *datalen, 623 const char **dptr, unsigned int *datalen,
607 unsigned int cseq, unsigned int code) 624 unsigned int cseq, unsigned int code)
608{ 625{
626 enum ip_conntrack_info ctinfo;
627 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
628
609 if ((code >= 100 && code <= 199) || 629 if ((code >= 100 && code <= 199) ||
610 (code >= 200 && code <= 299)) 630 (code >= 200 && code <= 299))
611 return process_sdp(skb, dptr, datalen, cseq); 631 return process_sdp(skb, dptr, datalen, cseq);
612 632 else {
613 return NF_ACCEPT; 633 flush_expectations(ct);
634 return NF_ACCEPT;
635 }
614} 636}
615 637
616static int process_update_response(struct sk_buff *skb, 638static int process_update_response(struct sk_buff *skb,
617 const char **dptr, unsigned int *datalen, 639 const char **dptr, unsigned int *datalen,
618 unsigned int cseq, unsigned int code) 640 unsigned int cseq, unsigned int code)
619{ 641{
642 enum ip_conntrack_info ctinfo;
643 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
644
620 if ((code >= 100 && code <= 199) || 645 if ((code >= 100 && code <= 199) ||
621 (code >= 200 && code <= 299)) 646 (code >= 200 && code <= 299))
622 return process_sdp(skb, dptr, datalen, cseq); 647 return process_sdp(skb, dptr, datalen, cseq);
623 648 else {
624 return NF_ACCEPT; 649 flush_expectations(ct);
650 return NF_ACCEPT;
651 }
625} 652}
626 653
627static int process_prack_response(struct sk_buff *skb, 654static int process_prack_response(struct sk_buff *skb,
628 const char **dptr, unsigned int *datalen, 655 const char **dptr, unsigned int *datalen,
629 unsigned int cseq, unsigned int code) 656 unsigned int cseq, unsigned int code)
630{ 657{
658 enum ip_conntrack_info ctinfo;
659 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
660
631 if ((code >= 100 && code <= 199) || 661 if ((code >= 100 && code <= 199) ||
632 (code >= 200 && code <= 299)) 662 (code >= 200 && code <= 299))
633 return process_sdp(skb, dptr, datalen, cseq); 663 return process_sdp(skb, dptr, datalen, cseq);
664 else {
665 flush_expectations(ct);
666 return NF_ACCEPT;
667 }
668}
669
670static int process_bye_request(struct sk_buff *skb,
671 const char **dptr, unsigned int *datalen,
672 unsigned int cseq)
673{
674 enum ip_conntrack_info ctinfo;
675 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
634 676
677 flush_expectations(ct);
635 return NF_ACCEPT; 678 return NF_ACCEPT;
636} 679}
637 680
@@ -640,6 +683,7 @@ static const struct sip_handler sip_handlers[] = {
640 SIP_HANDLER("UPDATE", process_sdp, process_update_response), 683 SIP_HANDLER("UPDATE", process_sdp, process_update_response),
641 SIP_HANDLER("ACK", process_sdp, NULL), 684 SIP_HANDLER("ACK", process_sdp, NULL),
642 SIP_HANDLER("PRACK", process_sdp, process_prack_response), 685 SIP_HANDLER("PRACK", process_sdp, process_prack_response),
686 SIP_HANDLER("BYE", process_bye_request, NULL),
643}; 687};
644 688
645static int process_sip_response(struct sk_buff *skb, 689static int process_sip_response(struct sk_buff *skb,