]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - net/ipv4/route.c
net: Add dummy dst_ops->redirect method where needed.
[karo-tx-linux.git] / net / ipv4 / route.c
index f3d25656ddb061f066ab0ead9388b1dd26b2f570..23bbe29b3bba6ef7e484ff7a455e1ca146ed8b11 100644 (file)
@@ -1345,50 +1345,6 @@ reject_redirect:
        ;
 }
 
-/* called in rcu_read_lock() section */
-void ip_rt_redirect(struct sk_buff *skb, __be32 new_gw)
-{
-       const struct iphdr *iph = (const struct iphdr *) skb->data;
-       __be32 daddr = iph->daddr;
-       __be32 saddr = iph->saddr;
-       struct net_device *dev = skb->dev;
-       int    ikeys[2] = { dev->ifindex, 0 };
-       __be32 skeys[2] = { saddr, 0 };
-       struct net *net;
-       int s, i;
-
-       net = dev_net(dev);
-       for (s = 0; s < 2; s++) {
-               for (i = 0; i < 2; i++) {
-                       unsigned int hash;
-                       struct rtable __rcu **rthp;
-                       struct rtable *rt;
-
-                       hash = rt_hash(daddr, skeys[s], ikeys[i], rt_genid(net));
-
-                       rthp = &rt_hash_table[hash].chain;
-
-                       while ((rt = rcu_dereference(*rthp)) != NULL) {
-                               rthp = &rt->dst.rt_next;
-
-                               if (rt->rt_key_dst != daddr ||
-                                   rt->rt_key_src != skeys[s] ||
-                                   rt->rt_oif != ikeys[i] ||
-                                   rt_is_input_route(rt) ||
-                                   rt_is_expired(rt) ||
-                                   !net_eq(dev_net(rt->dst.dev), net) ||
-                                   rt->dst.error ||
-                                   rt->dst.dev != dev)
-                                       continue;
-
-                               ip_do_redirect(&rt->dst, skb);
-                       }
-               }
-       }
-       return;
-
-}
-
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
 {
        struct rtable *rt = (struct rtable *)dst;
@@ -1590,6 +1546,34 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu)
 }
 EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu);
 
+void ipv4_redirect(struct sk_buff *skb, struct net *net,
+                  int oif, u32 mark, u8 protocol, int flow_flags)
+{
+       const struct iphdr *iph = (const struct iphdr *)skb->data;
+       struct flowi4 fl4;
+       struct rtable *rt;
+
+       flowi4_init_output(&fl4, oif, mark, RT_TOS(iph->tos), RT_SCOPE_UNIVERSE,
+                          protocol, flow_flags, iph->daddr, iph->saddr, 0, 0);
+       rt = __ip_route_output_key(net, &fl4);
+       if (!IS_ERR(rt)) {
+               ip_do_redirect(&rt->dst, skb);
+               ip_rt_put(rt);
+       }
+}
+EXPORT_SYMBOL_GPL(ipv4_redirect);
+
+void ipv4_sk_redirect(struct sk_buff *skb, struct sock *sk)
+{
+       const struct inet_sock *inet = inet_sk(sk);
+
+       return ipv4_redirect(skb, sock_net(sk), sk->sk_bound_dev_if,
+                            sk->sk_mark,
+                            inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,
+                            inet_sk_flowi_flags(sk));
+}
+EXPORT_SYMBOL_GPL(ipv4_sk_redirect);
+
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
 {
        struct rtable *rt = (struct rtable *) dst;
@@ -2607,6 +2591,10 @@ static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
 {
 }
 
+static void ipv4_rt_blackhole_redirect(struct dst_entry *dst, struct sk_buff *skb)
+{
+}
+
 static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst,
                                          unsigned long old)
 {
@@ -2621,6 +2609,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
        .mtu                    =       ipv4_blackhole_mtu,
        .default_advmss         =       ipv4_default_advmss,
        .update_pmtu            =       ipv4_rt_blackhole_update_pmtu,
+       .redirect               =       ipv4_rt_blackhole_redirect,
        .cow_metrics            =       ipv4_rt_blackhole_cow_metrics,
        .neigh_lookup           =       ipv4_neigh_lookup,
 };