Commit fc39cece authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji

[IPV6]: Export ip6_route_me_harder for netfilter and add ipv6_addr_prefix.

parent 7a4663bc
...@@ -30,6 +30,8 @@ extern void ip6_route_input(struct sk_buff *skb); ...@@ -30,6 +30,8 @@ extern void ip6_route_input(struct sk_buff *skb);
extern struct dst_entry * ip6_route_output(struct sock *sk, extern struct dst_entry * ip6_route_output(struct sock *sk,
struct flowi *fl); struct flowi *fl);
extern int ip6_route_me_harder(struct sk_buff *skb);
extern void ip6_route_init(void); extern void ip6_route_init(void);
extern void ip6_route_cleanup(void); extern void ip6_route_cleanup(void);
......
...@@ -134,7 +134,7 @@ int ip6_output(struct sk_buff *skb) ...@@ -134,7 +134,7 @@ int ip6_output(struct sk_buff *skb)
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
static int route6_me_harder(struct sk_buff *skb) int ip6_route_me_harder(struct sk_buff *skb)
{ {
struct ipv6hdr *iph = skb->nh.ipv6h; struct ipv6hdr *iph = skb->nh.ipv6h;
struct dst_entry *dst; struct dst_entry *dst;
...@@ -152,7 +152,7 @@ static int route6_me_harder(struct sk_buff *skb) ...@@ -152,7 +152,7 @@ static int route6_me_harder(struct sk_buff *skb)
if (dst->error) { if (dst->error) {
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_DEBUG "route6_me_harder: No more route.\n"); printk(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -168,7 +168,7 @@ static inline int ip6_maybe_reroute(struct sk_buff *skb) ...@@ -168,7 +168,7 @@ static inline int ip6_maybe_reroute(struct sk_buff *skb)
{ {
#ifdef CONFIG_NETFILTER #ifdef CONFIG_NETFILTER
if (skb->nfcache & NFC_ALTERED){ if (skb->nfcache & NFC_ALTERED){
if (route6_me_harder(skb) != 0){ if (ip6_route_me_harder(skb) != 0){
kfree_skb(skb); kfree_skb(skb);
return -EINVAL; return -EINVAL;
} }
......
#include <linux/config.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/protocol.h> #include <net/protocol.h>
#include <net/ipv6.h> #include <net/ipv6.h>
...@@ -11,6 +12,9 @@ EXPORT_SYMBOL(ndisc_mc_map); ...@@ -11,6 +12,9 @@ EXPORT_SYMBOL(ndisc_mc_map);
EXPORT_SYMBOL(register_inet6addr_notifier); EXPORT_SYMBOL(register_inet6addr_notifier);
EXPORT_SYMBOL(unregister_inet6addr_notifier); EXPORT_SYMBOL(unregister_inet6addr_notifier);
EXPORT_SYMBOL(ip6_route_output); EXPORT_SYMBOL(ip6_route_output);
#ifdef CONFIG_NETFILTER
EXPORT_SYMBOL(ip6_route_me_harder);
#endif
EXPORT_SYMBOL(addrconf_lock); EXPORT_SYMBOL(addrconf_lock);
EXPORT_SYMBOL(ipv6_setsockopt); EXPORT_SYMBOL(ipv6_setsockopt);
EXPORT_SYMBOL(ipv6_getsockopt); EXPORT_SYMBOL(ipv6_getsockopt);
......
...@@ -326,45 +326,6 @@ ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info, void *data) ...@@ -326,45 +326,6 @@ ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info, void *data)
return status; return status;
} }
/*
* Taken from net/ipv6/ip6_output.c
*
* We should use the one there, but is defined static
* so we put this just here and let the things as
* they are now.
*
* If that one is modified, this one should be modified too.
*/
static int
route6_me_harder(struct sk_buff *skb)
{
struct ipv6hdr *iph = skb->nh.ipv6h;
struct dst_entry *dst;
struct flowi fl;
fl.proto = iph->nexthdr;
fl.fl6_dst = &iph->daddr;
fl.fl6_src = &iph->saddr;
fl.oif = skb->sk ? skb->sk->bound_dev_if : 0;
fl.fl6_flowlabel = 0;
fl.uli_u.ports.dport = 0;
fl.uli_u.ports.sport = 0;
dst = ip6_route_output(skb->sk, &fl);
if (dst->error) {
if (net_ratelimit())
printk(KERN_DEBUG "route6_me_harder: No more route.\n");
return -EINVAL;
}
/* Drop old route. */
dst_release(skb->dst);
skb->dst = dst;
return 0;
}
static int static int
ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
{ {
...@@ -410,7 +371,7 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) ...@@ -410,7 +371,7 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
struct ipv6hdr *iph = e->skb->nh.ipv6h; struct ipv6hdr *iph = e->skb->nh.ipv6h;
if (ipv6_addr_cmp(&iph->daddr, &e->rt_info.daddr) || if (ipv6_addr_cmp(&iph->daddr, &e->rt_info.daddr) ||
ipv6_addr_cmp(&iph->saddr, &e->rt_info.saddr)) ipv6_addr_cmp(&iph->saddr, &e->rt_info.saddr))
return route6_me_harder(e->skb); return ip6_route_me_harder(e->skb);
} }
return 0; return 0;
} }
......
...@@ -574,15 +574,17 @@ static int ip6_dst_gc() ...@@ -574,15 +574,17 @@ static int ip6_dst_gc()
Remove it only when all the things will work! Remove it only when all the things will work!
*/ */
static void ipv6_wash_prefix(struct in6_addr *pfx, int plen) static void ipv6_addr_prefix(struct in6_addr *pfx,
const struct in6_addr *addr, int plen)
{ {
int b = plen&0x7; int b = plen&0x7;
int o = (plen + 7)>>3; int o = plen>>3;
memcpy(prefix, addr, o);
if (o < 16) if (o < 16)
memset(pfx->s6_addr + o, 0, 16 - o); memset(pfx->s6_addr + o, 0, 16 - o);
if (b != 0) if (b != 0)
pfx->s6_addr[plen>>3] &= (0xFF<<(8-b)); pfx->s6_addr[o] = addr->s6_addr[o]&(0xff00 >> b);
} }
static int ipv6_get_mtu(struct net_device *dev) static int ipv6_get_mtu(struct net_device *dev)
...@@ -655,16 +657,16 @@ int ip6_route_add(struct in6_rtmsg *rtmsg) ...@@ -655,16 +657,16 @@ int ip6_route_add(struct in6_rtmsg *rtmsg)
goto out; goto out;
} }
ipv6_addr_copy(&rt->rt6i_dst.addr, &rtmsg->rtmsg_dst); ipv6_addr_prefix(&rt->rt6i_dst.addr,
&rtmsg->rtmsg_dst, rtmsg->rtmsg_dst_len);
rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len; rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len;
if (rt->rt6i_dst.plen == 128) if (rt->rt6i_dst.plen == 128)
rt->u.dst.flags = DST_HOST; rt->u.dst.flags = DST_HOST;
ipv6_wash_prefix(&rt->rt6i_dst.addr, rt->rt6i_dst.plen);
#ifdef CONFIG_IPV6_SUBTREES #ifdef CONFIG_IPV6_SUBTREES
ipv6_addr_copy(&rt->rt6i_src.addr, &rtmsg->rtmsg_src); ipv6_addr_prefix(&rt->rt6i_src.addr,
&rtmsg->rtmsg_src, rtmsg->rtmsg_src_len);
rt->rt6i_src.plen = rtmsg->rtmsg_src_len; rt->rt6i_src.plen = rtmsg->rtmsg_src_len;
ipv6_wash_prefix(&rt->rt6i_src.addr, rt->rt6i_src.plen);
#endif #endif
rt->rt6i_metric = rtmsg->rtmsg_metric; rt->rt6i_metric = rtmsg->rtmsg_metric;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment