# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1515 -> 1.1516 # net/ipv6/netfilter/Makefile 1.12 -> 1.13 # net/ipv6/ipv6_syms.c 1.18 -> 1.19 # net/ipv6/netfilter/Kconfig 1.4 -> 1.5 # (new) -> 1.1 net/ipv6/netfilter/ip6_proxy_nd.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 04/01/13 vnuorval@xxxxxxxxxxxxxxxxxxxxxxx 1.1516 # A proxy needs to capture and process Neighbor Solicitations on behalf of the proxied node. # Normal multicast NS messages are already handled by the existing neigbor discovery code, # but unicast NS messages used for Neighbor Unreachability Detection will only be handled by # the proxy if it captures the packets for local processing using netfilter. # -------------------------------------------- # diff -Nru a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c --- a/net/ipv6/ipv6_syms.c Tue Jan 13 21:02:18 2004 +++ b/net/ipv6/ipv6_syms.c Tue Jan 13 21:02:18 2004 @@ -17,6 +17,9 @@ EXPORT_SYMBOL(ip6_route_output); #ifdef CONFIG_NETFILTER EXPORT_SYMBOL(ip6_route_me_harder); +EXPORT_SYMBOL(ipv6_skip_exthdr); +EXPORT_SYMBOL(ip6_input); +EXPORT_SYMBOL(nd_tbl); #endif EXPORT_SYMBOL(addrconf_lock); EXPORT_SYMBOL(ipv6_setsockopt); diff -Nru a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig --- a/net/ipv6/netfilter/Kconfig Tue Jan 13 21:02:18 2004 +++ b/net/ipv6/netfilter/Kconfig Tue Jan 13 21:02:18 2004 @@ -218,5 +218,14 @@ To compile it as a module, choose M here. If unsure, say N. #dep_tristate ' LOG target support' CONFIG_IP6_NF_TARGET_LOG $CONFIG_IP6_NF_IPTABLES + +config IP6_NF_PROXY_ND + tristate "Complete proxy Neigbor Discovery support" + help + This filter allows the proxy to process unicast Neighbor + Unreachability Probes as well as normal multicast + Neighbor Solicitations sent to the proxied node. + + To compile it as a module, choose M here. If unsure, say N. endmenu diff -Nru a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile --- a/net/ipv6/netfilter/Makefile Tue Jan 13 21:02:18 2004 +++ b/net/ipv6/netfilter/Makefile Tue Jan 13 21:02:18 2004 @@ -22,3 +22,4 @@ obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o obj-$(CONFIG_IP6_NF_MATCH_HL) += ip6t_hl.o +obj-$(CONFIG_IP6_NF_PROXY_ND) += ip6_proxy_nd.o diff -Nru a/net/ipv6/netfilter/ip6_proxy_nd.c b/net/ipv6/netfilter/ip6_proxy_nd.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/net/ipv6/netfilter/ip6_proxy_nd.c Tue Jan 13 21:02:18 2004 @@ -0,0 +1,100 @@ +/* + * Copyright (C)2003 Helsinki University of Technology + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Linux INET6 implementation + * + * nf hook for capturing unicast neighbor discovery messages so a proxy + * can participate in Neighbor Unreachability Detection on behalf of its + * client + * + * Authors + * Ville Nuorvala + */ + +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Ville Nuorvala "); +MODULE_DESCRIPTION("IPv6 Proxy ND filter"); + + +static unsigned int ip6_proxy_nd_hook(unsigned int hooknum, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + struct sk_buff *skb = *pskb; + struct ipv6hdr *ipv6h = skb->nh.ipv6h; + u8 nexthdr = ipv6h->nexthdr; + int offset; + struct in6_addr *daddr = &skb->nh.ipv6h->daddr; + struct icmp6hdr msg; + + if (ipv6_ext_hdr(nexthdr)) { + offset = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), + &nexthdr, + skb->len - sizeof(struct ipv6hdr)); + if (offset < 0) + return NF_ACCEPT; + } else + offset = sizeof(struct ipv6hdr); + + /* capture unicast NUD probes on behalf of the proxied node */ + if (nexthdr == IPPROTO_ICMPV6 && + ipv6_addr_type(daddr) & IPV6_ADDR_UNICAST && + !skb_copy_bits(skb, offset, &msg, sizeof(msg))) { + int iif; + struct net_device *dev; + switch (msg.icmp6_type) { + case NDISC_NEIGHBOUR_SOLICITATION: + iif = ((struct inet6_skb_parm *)skb->cb)->iif; + dev = __dev_get_by_index(iif); + if (dev && pneigh_lookup(&nd_tbl, daddr, dev, 0)) { + ip6_input(skb); + return NF_STOLEN; + } + } + } + return NF_ACCEPT; +} + +static struct nf_hook_ops ip6_proxy_nd_ops = { + .hook = ip6_proxy_nd_hook, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_IP6_PRE_ROUTING, + .priority = NF_IP6_PRI_LAST, +}; + + +static int __init ip6_proxy_nd_init(void) +{ + return nf_register_hook(&ip6_proxy_nd_ops); +} + +static void __exit ip6_proxy_nd_exit(void) +{ + nf_unregister_hook(&ip6_proxy_nd_ops); +} + +module_init(ip6_proxy_nd_init); +module_exit(ip6_proxy_nd_exit); +