Hi Alin,

On Thu, Nov 29, 2018 at 10:28:51AM +0100, Alin Nastac wrote:
> Allow media streams that are not passing through this router.
> 
> When enabled, the sip_external_media logic will leave SDP
> payload untouched when it detects that interface towards INVITEd
> party is the same with the one towards media endpoint.

Sorry for catching up this now.

Would you make for me a more detailed scenario?

I love to keep such in the patch description, they are good for the
record, specifically for this "tricky" helper.

Thanks!

> Signed-off-by: Alin Nastac <alin.nas...@gmail.com>
> ---
>  net/netfilter/nf_conntrack_sip.c | 38 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 38 insertions(+)
> 
> diff --git a/net/netfilter/nf_conntrack_sip.c 
> b/net/netfilter/nf_conntrack_sip.c
> index c8d2b66..5416c08 100644
> --- a/net/netfilter/nf_conntrack_sip.c
> +++ b/net/netfilter/nf_conntrack_sip.c
> @@ -21,6 +21,8 @@
>  #include <linux/tcp.h>
>  #include <linux/netfilter.h>
>  
> +#include <net/route.h>
> +#include <net/ip6_route.h>
>  #include <net/netfilter/nf_conntrack.h>
>  #include <net/netfilter/nf_conntrack_core.h>
>  #include <net/netfilter/nf_conntrack_expect.h>
> @@ -54,6 +56,11 @@ module_param(sip_direct_media, int, 0600);
>  MODULE_PARM_DESC(sip_direct_media, "Expect Media streams between signalling "
>                                  "endpoints only (default 1)");
>  
> +static int sip_external_media __read_mostly = 0;
> +module_param(sip_external_media, int, 0600);
> +MODULE_PARM_DESC(sip_external_media, "Expect Media streams between external "
> +                                  "endpoints (default 0)");
> +
>  const struct nf_nat_sip_hooks *nf_nat_sip_hooks;
>  EXPORT_SYMBOL_GPL(nf_nat_sip_hooks);
>  
> @@ -861,6 +868,37 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, 
> unsigned int protoff,
>               if (!nf_inet_addr_cmp(daddr, &ct->tuplehash[dir].tuple.src.u3))
>                       return NF_ACCEPT;
>               saddr = &ct->tuplehash[!dir].tuple.src.u3;
> +     } else if (sip_external_media) {
> +             struct net_device *dev = skb_dst(skb)->dev;
> +             struct net *net = dev_net(dev);
> +             struct rtable *rt;
> +             struct flowi4 fl4 = {};
> +             struct flowi6 fl6 = {};
> +             struct dst_entry *dst = NULL;
> +
> +             switch (nf_ct_l3num(ct)) {
> +                     case NFPROTO_IPV4:
> +                             fl4.daddr = daddr->ip;
> +                             rt = ip_route_output_key(net, &fl4);
> +                             if (!IS_ERR(rt))
> +                                     dst = &rt->dst;
> +                             break;
> +
> +                     case NFPROTO_IPV6:
> +                             fl6.daddr = daddr->in6;
> +                             dst = ip6_route_output(net, NULL, &fl6);
> +                             if (dst->error) {
> +                                     dst_release(dst);
> +                                     dst = NULL;
> +                             }
> +                             break;
> +             }
> +
> +             /* Don't predict any conntracks when media endpoint is reachable
> +              * through the same interface as the signalling peer.
> +              */
> +             if (dst && dst->dev == dev)
> +                     return NF_ACCEPT;
>       }
>  
>       /* We need to check whether the registration exists before attempting
> -- 
> 2.7.4
> 

Reply via email to