From: Maciej Żenczykowski Date: Mon, 27 Sep 2010 00:07:02 +0000 (+0000) Subject: ipv6: Implement Any-IP support for IPv6. X-Git-Tag: MMI-PSA29.97-13-9~21994^2~320 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=ab79ad14a2d51e95f0ac3cef7cd116a57089ba82;p=GitHub%2FMotorolaMobilityLLC%2Fkernel-slsi.git ipv6: Implement Any-IP support for IPv6. AnyIP is the capability to receive packets and establish incoming connections on IPs we have not explicitly configured on the machine. An example use case is to configure a machine to accept all incoming traffic on eth0, and leave the policy of whether traffic for a given IP should be delivered to the machine up to the load balancer. Can be setup as follows: ip -6 rule from all iif eth0 lookup 200 ip -6 route add local default dev lo table 200 (in this case for all IPv6 addresses) Signed-off-by: Maciej Żenczykowski Signed-off-by: David S. Miller --- diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 25b0beda4331..25476e7e708b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1169,6 +1169,8 @@ int ip6_route_add(struct fib6_config *cfg) if (addr_type & IPV6_ADDR_MULTICAST) rt->dst.input = ip6_mc_input; + else if (cfg->fc_flags & RTF_LOCAL) + rt->dst.input = ip6_input; else rt->dst.input = ip6_forward; @@ -1190,7 +1192,8 @@ int ip6_route_add(struct fib6_config *cfg) they would result in kernel looping; promote them to reject routes */ if ((cfg->fc_flags & RTF_REJECT) || - (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { + (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK) + && !(cfg->fc_flags&RTF_LOCAL))) { /* hold loopback dev/idev if we haven't done so. */ if (dev != net->loopback_dev) { if (dev) { @@ -2082,6 +2085,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, if (rtm->rtm_type == RTN_UNREACHABLE) cfg->fc_flags |= RTF_REJECT; + if (rtm->rtm_type == RTN_LOCAL) + cfg->fc_flags |= RTF_LOCAL; + cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; cfg->fc_nlinfo.nlh = nlh; cfg->fc_nlinfo.nl_net = sock_net(skb->sk); @@ -2202,6 +2208,8 @@ static int rt6_fill_node(struct net *net, NLA_PUT_U32(skb, RTA_TABLE, table); if (rt->rt6i_flags&RTF_REJECT) rtm->rtm_type = RTN_UNREACHABLE; + else if (rt->rt6i_flags&RTF_LOCAL) + rtm->rtm_type = RTN_LOCAL; else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) rtm->rtm_type = RTN_LOCAL; else