aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-16 11:33:06 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-16 11:33:06 -0400
commit5206a79d7b217c139116fc6faef55d1c0e65c800 (patch)
tree334717cbd3ae9752351ec81acc088577142c8cab /net/ipv6/route.c
parent29da7eb0ec69245c6e9b4eb5bdaa04af685f5c4f (diff)
parent3f5306927d800306ebba542438cfdf1a1c418376 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (25 commits) [Bluetooth] Use work queue to trigger URB submission [Bluetooth] Add locking for bt_proto array manipulation [Bluetooth] Check if DLC is still attached to the TTY [Bluetooth] Fix reference count when connection lookup fails [Bluetooth] Disconnect HID interrupt channel first [Bluetooth] Support concurrent connect requests [Bluetooth] Make use of virtual devices tree [Bluetooth] Handle return values from driver core functions [Bluetooth] Fix compat ioctl for BNEP, CMTP and HIDP [IPV6] sit: Add missing MODULE_LICENSE [IPV6]: Remove bogus WARN_ON in Proxy-NA handling. [IPv6] rules: Use RT6_LOOKUP_F_HAS_SADDR and fix source based selectors [XFRM]: Fix xfrm_state_num going negative. [NET]: reduce sizeof(struct inet_peer), cleanup, change in peer_check_expire() NetLabel: the CIPSOv4 passthrough mapping does not pass categories correctly NetLabel: better error handling involving mls_export_cat() NetLabel: only deref the CIPSOv4 standard map fields when using standard mapping [BRIDGE]: flush forwarding table when device carrier off [NETFILTER]: ctnetlink: Remove debugging messages [NETFILTER]: Update MAINTAINERS entry ...
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d6b4b4f48d18..a1b0f075462e 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -529,13 +529,17 @@ struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
529 .nl_u = { 529 .nl_u = {
530 .ip6_u = { 530 .ip6_u = {
531 .daddr = *daddr, 531 .daddr = *daddr,
532 /* TODO: saddr */
533 }, 532 },
534 }, 533 },
535 }; 534 };
536 struct dst_entry *dst; 535 struct dst_entry *dst;
537 int flags = strict ? RT6_LOOKUP_F_IFACE : 0; 536 int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
538 537
538 if (saddr) {
539 memcpy(&fl.fl6_src, saddr, sizeof(*saddr));
540 flags |= RT6_LOOKUP_F_HAS_SADDR;
541 }
542
539 dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup); 543 dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup);
540 if (dst->error == 0) 544 if (dst->error == 0)
541 return (struct rt6_info *) dst; 545 return (struct rt6_info *) dst;
@@ -697,6 +701,7 @@ out2:
697void ip6_route_input(struct sk_buff *skb) 701void ip6_route_input(struct sk_buff *skb)
698{ 702{
699 struct ipv6hdr *iph = skb->nh.ipv6h; 703 struct ipv6hdr *iph = skb->nh.ipv6h;
704 int flags = RT6_LOOKUP_F_HAS_SADDR;
700 struct flowi fl = { 705 struct flowi fl = {
701 .iif = skb->dev->ifindex, 706 .iif = skb->dev->ifindex,
702 .nl_u = { 707 .nl_u = {
@@ -711,7 +716,9 @@ void ip6_route_input(struct sk_buff *skb)
711 }, 716 },
712 .proto = iph->nexthdr, 717 .proto = iph->nexthdr,
713 }; 718 };
714 int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0; 719
720 if (rt6_need_strict(&iph->daddr))
721 flags |= RT6_LOOKUP_F_IFACE;
715 722
716 skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input); 723 skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input);
717} 724}
@@ -794,6 +801,9 @@ struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
794 if (rt6_need_strict(&fl->fl6_dst)) 801 if (rt6_need_strict(&fl->fl6_dst))
795 flags |= RT6_LOOKUP_F_IFACE; 802 flags |= RT6_LOOKUP_F_IFACE;
796 803
804 if (!ipv6_addr_any(&fl->fl6_src))
805 flags |= RT6_LOOKUP_F_HAS_SADDR;
806
797 return fib6_rule_lookup(fl, flags, ip6_pol_route_output); 807 return fib6_rule_lookup(fl, flags, ip6_pol_route_output);
798} 808}
799 809
@@ -1345,6 +1355,7 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1345 struct in6_addr *gateway, 1355 struct in6_addr *gateway,
1346 struct net_device *dev) 1356 struct net_device *dev)
1347{ 1357{
1358 int flags = RT6_LOOKUP_F_HAS_SADDR;
1348 struct ip6rd_flowi rdfl = { 1359 struct ip6rd_flowi rdfl = {
1349 .fl = { 1360 .fl = {
1350 .oif = dev->ifindex, 1361 .oif = dev->ifindex,
@@ -1357,7 +1368,9 @@ static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1357 }, 1368 },
1358 .gateway = *gateway, 1369 .gateway = *gateway,
1359 }; 1370 };
1360 int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0; 1371
1372 if (rt6_need_strict(dest))
1373 flags |= RT6_LOOKUP_F_IFACE;
1361 1374
1362 return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect); 1375 return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect);
1363} 1376}