OSDN Git Service

netfilter: nf_conntrack_sip: remove direct dependency on IPv6
authorAlin Nastac <alin.nastac@gmail.com>
Mon, 11 Mar 2019 16:18:42 +0000 (17:18 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 18 Mar 2019 15:11:54 +0000 (16:11 +0100)
Previous implementation was not usable with CONFIG_IPV6=m.

Fixes: a3419ce3356c ("netfilter: nf_conntrack_sip: add sip_external_media logic")
Signed-off-by: Alin Nastac <alin.nastac@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_conntrack_sip.c

index f067c6b..39fcc1e 100644 (file)
@@ -20,9 +20,9 @@
 #include <linux/udp.h>
 #include <linux/tcp.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.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>
@@ -871,38 +871,33 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff,
        } 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 = {};
-#if IS_ENABLED(CONFIG_IPV6)
-               struct flowi6 fl6 = {};
-#endif
+               struct flowi fl;
                struct dst_entry *dst = NULL;
 
+               memset(&fl, 0, sizeof(fl));
+
                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;
+                               fl.u.ip4.daddr = daddr->ip;
+                               nf_ip_route(net, &dst, &fl, false);
                                break;
 
-#if IS_ENABLED(CONFIG_IPV6)
                        case NFPROTO_IPV6:
-                               fl6.daddr = daddr->in6;
-                               dst = ip6_route_output(net, NULL, &fl6);
-                               if (dst->error) {
-                                       dst_release(dst);
-                                       dst = NULL;
-                               }
+                               fl.u.ip6.daddr = daddr->in6;
+                               nf_ip6_route(net, &dst, &fl, false);
                                break;
-#endif
                }
 
                /* 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;
+               if (dst) {
+                       bool external_media = (dst->dev == dev);
+
+                       dst_release(dst);
+                       if (external_media)
+                               return NF_ACCEPT;
+               }
        }
 
        /* We need to check whether the registration exists before attempting