[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4AB94D2C.4000006@gmail.com>
Date: Wed, 23 Sep 2009 00:18:20 +0200
From: Eric Dumazet <eric.dumazet@...il.com>
To: Alexandre Cassen <acassen@...ebox.fr>
CC: netdev@...r.kernel.org
Subject: Re: [PATCH][RESEND 3] IPv6: 6rd tunnel mode
Alexandre Cassen a écrit :
> This patch add support to 6rd tunnel mode as described into
> draft-despres-6rd-03.
>
> Patch history :
> * http://patchwork.ozlabs.org/patch/26870/
> * http://patchwork.ozlabs.org/patch/34026/
> * http://patchwork.ozlabs.org/patch/34045/
>
> IPv6 rapid deployment (draft-despres-6rd-03) builds upon mechanisms
> of 6to4 (RFC3056) to enable a service provider to rapidly deploy IPv6
> unicast service to IPv4 sites to which it provides customer premise
> equipment. Like 6to4, it utilizes stateless IPv6 in IPv4 encapsulation
> in order to transit IPv4-only network infrastructure. Unlike 6to4, a
> 6rd service provider uses an IPv6 prefix of its own in place of the
> fixed 6to4 prefix.
>
> Signed-off-by: Alexandre Cassen <acassen@...ebox.fr>
> ---
> include/linux/if_tunnel.h | 10 +++++
> include/net/ipip.h | 2 +
> net/ipv6/Kconfig | 13 +++++++
> net/ipv6/sit.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 109 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h
> index 5eb9b0f..0d44376 100644
> --- a/include/linux/if_tunnel.h
> +++ b/include/linux/if_tunnel.h
> @@ -15,6 +15,10 @@
> #define SIOCADDPRL (SIOCDEVPRIVATE + 5)
> #define SIOCDELPRL (SIOCDEVPRIVATE + 6)
> #define SIOCCHGPRL (SIOCDEVPRIVATE + 7)
> +#define SIOCGET6RD (SIOCDEVPRIVATE + 8)
> +#define SIOCADD6RD (SIOCDEVPRIVATE + 9)
> +#define SIOCDEL6RD (SIOCDEVPRIVATE + 10)
> +#define SIOCCHG6RD (SIOCDEVPRIVATE + 11)
>
> #define GRE_CSUM __cpu_to_be16(0x8000)
> #define GRE_ROUTING __cpu_to_be16(0x4000)
> @@ -51,6 +55,12 @@ struct ip_tunnel_prl {
> /* PRL flags */
> #define PRL_DEFAULT 0x0001
>
> +/* 6RD parms */
> +struct ip_tunnel_6rd {
> + struct in6_addr addr;
> + __u8 prefixlen;
> +};
> +
> enum
> {
> IFLA_GRE_UNSPEC,
> diff --git a/include/net/ipip.h b/include/net/ipip.h
> index 5d3036f..fa92c41 100644
> --- a/include/net/ipip.h
> +++ b/include/net/ipip.h
> @@ -26,6 +26,8 @@ struct ip_tunnel
>
> struct ip_tunnel_prl_entry *prl; /* potential router list */
> unsigned int prl_count; /* # of entries in PRL */
> +
> + struct ip_tunnel_6rd ip6rd_prefix; /* 6RD SP prefix */
> };
>
> /* ISATAP: default interval between RS in secondy */
> diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
> index ead6c7a..8b779f7 100644
> --- a/net/ipv6/Kconfig
> +++ b/net/ipv6/Kconfig
> @@ -170,6 +170,19 @@ config IPV6_SIT
>
> Saying M here will produce a module called sit. If unsure, say Y.
>
> +config IPV6_SIT_6RD
> + bool "IPv6: 6rd tunnel mode (EXPERIMENTAL)"
> + depends on IPV6_SIT && EXPERIMENTAL
> + default n
> + ---help---
> + IPv6 rapid deployment (draft-despres-6rd-03) builds upon mechanisms
> + of 6to4 (RFC3056) to enable a service provider to rapidly deploy IPv6
> + unicast service to IPv4 sites to which it provides customer premise
> + equipment. Like 6to4, it utilizes stateless IPv6 in IPv4 encapsulation
> + in order to transit IPv4-only network infrastructure. Unlike 6to4, a
> + 6rd service provider uses an IPv6 prefix of its own in place of the
> + fixed 6to4 prefix.
> +
> config IPV6_NDISC_NODETYPE
> bool
>
> diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
> index 0ae4f64..3587149 100644
> --- a/net/ipv6/sit.c
> +++ b/net/ipv6/sit.c
> @@ -604,6 +604,30 @@ static inline __be32 try_6to4(struct in6_addr *v6dst)
> return dst;
> }
>
> +#ifdef CONFIG_IPV6_SIT_6RD
> +/* Returns the embedded IPv4 address if the IPv6 address comes from
> + 6rd rule */
> +
> +static inline __be32 try_6rd(struct in6_addr *addr, u8 prefix_len, struct in6_addr *v6dst)
> +{
> + __be32 dst = 0;
> +
> + /* isolate addr according to mask */
> + if (ipv6_prefix_equal(v6dst, addr, prefix_len)) {
> + unsigned int d32_off, bits;
> +
> + d32_off = prefix_len >> 5;
> + bits = (prefix_len & 0x1f);
> +
> + dst = (ntohl(v6dst->s6_addr32[d32_off]) << bits);
> + if (bits)
> + dst |= ntohl(v6dst->s6_addr32[d32_off + 1]) >> (32 - bits);
> + dst = htonl(dst);
> + }
> + return dst;
> +}
> +#endif
> +
> /*
> * This function assumes it is being called from dev_queue_xmit()
> * and that skb is filled properly by that function.
> @@ -657,6 +681,13 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
> goto tx_error;
> }
>
> +#ifdef CONFIG_IPV6_SIT_6RD
> + if (!dst && tunnel->ip6rd_prefix.prefixlen)
> + dst = try_6rd(&tunnel->ip6rd_prefix.addr,
> + tunnel->ip6rd_prefix.prefixlen,
> + &iph6->daddr);
> + else
> +#endif
> if (!dst)
> dst = try_6to4(&iph6->daddr);
>
> @@ -848,6 +879,9 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
> int err = 0;
> struct ip_tunnel_parm p;
> struct ip_tunnel_prl prl;
> +#ifdef CONFIG_IPV6_SIT_6RD
> + struct ip_tunnel_6rd ip6rd;
> +#endif
> struct ip_tunnel *t;
> struct net *net = dev_net(dev);
> struct sit_net *sitn = net_generic(net, sit_net_id);
> @@ -987,6 +1021,56 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
> netdev_state_change(dev);
> break;
>
> +#ifdef CONFIG_IPV6_SIT_6RD
> + case SIOCGET6RD:
> + err = -EINVAL;
> + if (dev == sitn->fb_tunnel_dev)
> + goto done;
> + err = -ENOENT;
> + if (!(t = netdev_priv(dev)))
> + goto done;
> + memcpy(&ip6rd, &t->ip6rd_prefix, sizeof(ip6rd));
Just wondering why you need a temporary ip6rd here,
why dont you copy_to_user(ifr->ifr_ifru.ifru_data, &t->ip6rd_prefix, sizeof(ip6rd)); ?
> + if (copy_to_user(ifr->ifr_ifru.ifru_data, &ip6rd, sizeof(ip6rd)))
> + err = -EFAULT;
> + else
> + err = 0;
> + break;
> +
> + case SIOCADD6RD:
> + case SIOCDEL6RD:
> + case SIOCCHG6RD:
> + err = -EPERM;
> + if (!capable(CAP_NET_ADMIN))
> + goto done;
> + err = -EINVAL;
> + if (dev == sitn->fb_tunnel_dev)
> + goto done;
> + err = -EFAULT;
> + if (copy_from_user(&ip6rd, ifr->ifr_ifru.ifru_data, sizeof(ip6rd)))
> + goto done;
> + err = -ENOENT;
> + if (!(t = netdev_priv(dev)))
> + goto done;
> +
> + err = 0;
> + switch (cmd) {
> + case SIOCDEL6RD:
> + memset(&t->ip6rd_prefix, 0, sizeof(ip6rd));
> + break;
> + case SIOCADD6RD:
> + case SIOCCHG6RD:
> + if (ip6rd.prefixlen >= 95) {
> + err = -EINVAL;
> + goto done;
> + }
> + ipv6_addr_copy(&t->ip6rd_prefix.addr, &ip6rd.addr);
> + t->ip6rd_prefix.prefixlen = ip6rd.prefixlen;
> + break;
> + }
> + netdev_state_change(dev);
> + break;
> +#endif
> +
> default:
> err = -EINVAL;
> }
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists