: Make SIT tunnel work in net namespaces.
Subsystems (2)
cover : Make SIT tunnel work in net namespaces.
ipv4 tunnels are done - time to virtualize ipv6 tunnels.
PATCH 1/8 : Introduce empty struct sit_net and init/exit net ops.
--- net/ipv6/sit.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-)
net/ipv6/sit.c +50 -0
@@ -52,6 +52,8 @@#include <net/inet_ecn.h> #include <net/xfrm.h> #include <net/dsfield.h> +#include <net/net_namespace.h> +#include <net/netns/generic.h> /* This version of net/ipv6/sit.c is cloned of net/ipv4/ip_gre.c
@@ -66,6 +68,10 @@ static int ipip6_fb_tunnel_init(struct net_device *dev);static int ipip6_tunnel_init (struct net_device *dev);static void ipip6_tunnel_setup (struct net_device *dev); +static int sit_net_id; +struct sit_net { +}; +static struct net_device *ipip6_fb_tunnel_dev;static struct ip_tunnel *tunnels_r_l[HASH_SIZE ];
@@ -1068,6 +1074,41 @@ static void __exit sit_destroy_tunnels(void) } } +static int sit_init_net (struct net *net) +{ +int err; +struct sit_net *sitn; + + err = -ENOMEM ; + sitn =kmalloc (sizeof (struct sit_net ),GFP_KERNEL ); +if (sitn ==NULL ) + goto err_alloc; + + err =net_assign_generic (net, sit_net_id, sitn); +if (err <0 ) + goto err_assign; + +return 0 ; + +err_assign: +kfree (sitn); +err_alloc: +return err; +} + +static void sit_exit_net (struct net *net) +{ +struct sit_net *sitn; + + sitn =net_generic (net, sit_net_id); +kfree (sitn); +} + +static struct pernet_operations sit_net_ops = { + .init = sit_init_net, + .exit = sit_exit_net, +}; + static void __exit sit_cleanup(void) {xfrm4_tunnel_deregister (&sit_handler,AF_INET6 );
@@ -1076,6 +1117,8 @@ static void __exit sit_cleanup(void)sit_destroy_tunnels ();unregister_netdevice (ipip6_fb_tunnel_dev);rtnl_unlock (); + +unregister_pernet_gen_device (sit_net_id, &sit_net_ops); }static int __init sit_init (void )
@@ -1101,6 +1144,10 @@ static int __init sit_init(void)if ((err =register_netdev (ipip6_fb_tunnel_dev))) goto err2; + err =register_pernet_gen_device (&sit_net_id, &sit_net_ops); +if (err <0 ) + goto err3; + out:return err; err2:
@@ -1108,6 +1155,9 @@ static int __init sit_init(void) err1:xfrm4_tunnel_deregister (&sit_handler,AF_INET6 ); goto out; +err3: +unregister_netdevice (ipip6_fb_tunnel_dev); + goto err1; }module_init (sit_init);
Signature · 1 line
1.5.3.4
PATCH 2/8 : Add net/sit_net argument to some functions.
In reply to Pavel Emelyanov... to make them prepared for future hashes and fallback device move on the struct sit_net.
--- net/ipv6/sit.c | 49 ++++++++++++++++++++++++++++++------------------- 1 files changed, 30 insertions(+), 19 deletions(-)
net/ipv6/sit.c +30 -19
@@ -82,7 +82,8 @@ static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunnestatic DEFINE_RWLOCK (ipip6_lock); -static struct ip_tunnel *ipip6_tunnel_lookup (__be32 remote,__be32 local) +static struct ip_tunnel *ipip6_tunnel_lookup (struct net *net, +__be32 remote,__be32 local) {unsigned h0 =HASH (remote);unsigned h1 =HASH (local);
@@ -106,7 +107,8 @@ static struct ip_tunnel * ipip6_tunnel_lookup(__be32 remote, __be32 local)return NULL ; } -static struct ip_tunnel **__ipip6_bucket (struct ip_tunnel_parm *parms) +static struct ip_tunnel **__ipip6_bucket (struct sit_net *sitn, +struct ip_tunnel_parm *parms) {__be32 remote = parms->iph.daddr;__be32 local = parms->iph.saddr;
@@ -124,16 +126,17 @@ static struct ip_tunnel **__ipip6_bucket(struct ip_tunnel_parm *parms)return &tunnels[prio][h]; } -static inline struct ip_tunnel **ipip6_bucket (struct ip_tunnel *t) +static inline struct ip_tunnel **ipip6_bucket (struct sit_net *sitn, +struct ip_tunnel *t) { -return __ipip6_bucket (&t->parms); +return __ipip6_bucket (sitn, &t->parms); } -static void ipip6_tunnel_unlink (struct ip_tunnel *t) +static void ipip6_tunnel_unlink (struct sit_net *sitn,struct ip_tunnel *t) {struct ip_tunnel **tp; -for (tp =ipip6_bucket (t); *tp; tp = &(*tp)->next) { +for (tp =ipip6_bucket (sitn, t); *tp; tp = &(*tp)->next) {if (t == *tp) {write_lock_bh (&ipip6_lock); *tp = t->next;
@@ -143,9 +146,9 @@ static void ipip6_tunnel_unlink(struct ip_tunnel *t) } } -static void ipip6_tunnel_link (struct ip_tunnel *t) +static void ipip6_tunnel_link (struct sit_net *sitn,struct ip_tunnel *t) { -struct ip_tunnel **tp =ipip6_bucket (t); +struct ip_tunnel **tp =ipip6_bucket (sitn, t); t->next = *tp;write_lock_bh (&ipip6_lock);
@@ -153,15 +156,17 @@ static void ipip6_tunnel_link(struct ip_tunnel *t)write_unlock_bh (&ipip6_lock); } -static struct ip_tunnel *ipip6_tunnel_locate (struct ip_tunnel_parm *parms,int create) +static struct ip_tunnel *ipip6_tunnel_locate (struct net *net, +struct ip_tunnel_parm *parms,int create) {__be32 remote = parms->iph.daddr;__be32 local = parms->iph.saddr;struct ip_tunnel *t, **tp, *nt;struct net_device *dev;char name[IFNAMSIZ ]; +struct sit_net *sitn =net_generic (net, sit_net_id); -for (tp =__ipip6_bucket (parms); (t = *tp) !=NULL ; tp = &t->next) { +for (tp =__ipip6_bucket (sitn, parms); (t = *tp) !=NULL ; tp = &t->next) {if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)return t; }
@@ -194,7 +199,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, intdev_hold (dev); -ipip6_tunnel_link (nt); +ipip6_tunnel_link (sitn, nt);return nt; failed_free:
@@ -378,13 +383,16 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)static void ipip6_tunnel_uninit (struct net_device *dev) { +struct net *net =dev_net (dev); +struct sit_net *sitn =net_generic (net, sit_net_id); +if (dev == ipip6_fb_tunnel_dev) {write_lock_bh (&ipip6_lock); tunnels_wc[0 ] =NULL ;write_unlock_bh (&ipip6_lock);dev_put (dev); }else { -ipip6_tunnel_unlink (netdev_priv (dev)); +ipip6_tunnel_unlink (sitn,netdev_priv (dev));ipip6_tunnel_del_prl (netdev_priv (dev),NULL );dev_put (dev); }
@@ -436,7 +444,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info) err = -ENOENT ;read_lock (&ipip6_lock); - t =ipip6_tunnel_lookup (iph->daddr, iph->saddr); + t =ipip6_tunnel_lookup (&init_net, iph->daddr, iph->saddr);if (t ==NULL || t->parms.iph.daddr ==0 ) goto out;
@@ -556,7 +564,8 @@ static int ipip6_rcv(struct sk_buff *skb) iph =ip_hdr (skb);read_lock (&ipip6_lock); -if ((tunnel =ipip6_tunnel_lookup (iph->saddr, iph->daddr)) !=NULL ) { +if ((tunnel =ipip6_tunnel_lookup (&init_net, + iph->saddr, iph->daddr)) !=NULL ) {secpath_reset (skb); skb->mac_header = skb->network_header;skb_reset_network_header (skb);
@@ -847,6 +856,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)struct ip_tunnel_parm p;struct ip_tunnel_prl prl;struct ip_tunnel *t; +struct net *net =dev_net (dev); +struct sit_net *sitn =net_generic (net, sit_net_id);switch (cmd) {case SIOCGETTUNNEL :
@@ -856,7 +867,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) err = -EFAULT ;break ; } - t =ipip6_tunnel_locate (&p,0 ); + t =ipip6_tunnel_locate (net, &p,0 ); }if (t ==NULL ) t =netdev_priv (dev);
@@ -882,7 +893,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)if (p.iph.ttl) p.iph.frag_off |=htons (IP_DF ); - t =ipip6_tunnel_locate (&p, cmd ==SIOCADDTUNNEL ); + t =ipip6_tunnel_locate (net, &p, cmd ==SIOCADDTUNNEL );if (dev != ipip6_fb_tunnel_dev && cmd ==SIOCCHGTUNNEL ) {if (t !=NULL ) {
@@ -897,12 +908,12 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)break ; } t =netdev_priv (dev); -ipip6_tunnel_unlink (t); +ipip6_tunnel_unlink (sitn, t); t->parms.iph.saddr = p.iph.saddr; t->parms.iph.daddr = p.iph.daddr;memcpy (dev->dev_addr, &p.iph.saddr,4 );memcpy (dev->broadcast, &p.iph.daddr,4 ); -ipip6_tunnel_link (t); +ipip6_tunnel_link (sitn, t);netdev_state_change (dev); } }
@@ -934,7 +945,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)if (copy_from_user (&p, ifr->ifr_ifru.ifru_data,sizeof (p))) goto done; err = -ENOENT ; -if ((t =ipip6_tunnel_locate (&p,0 )) ==NULL ) +if ((t =ipip6_tunnel_locate (net, &p,0 )) ==NULL ) goto done; err = -EPERM ;if (t ==netdev_priv (ipip6_fb_tunnel_dev))
Signature · 1 line
1.5.3.4
PATCH 3/8 : Use proper net in hash-lookup functions.
In reply to Pavel EmelyanovReplace introduced in the previous patch init_net stubs with the proper net pointer.
--- net/ipv6/sit.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
net/ipv6/sit.c +2 -2
@@ -444,7 +444,7 @@ static int ipip6_err(struct sk_buff *skb, u32 info) err = -ENOENT ;read_lock (&ipip6_lock); - t =ipip6_tunnel_lookup (&init_net, iph->daddr, iph->saddr); + t =ipip6_tunnel_lookup (dev_net (skb->dev), iph->daddr, iph->saddr);if (t ==NULL || t->parms.iph.daddr ==0 ) goto out;
@@ -564,7 +564,7 @@ static int ipip6_rcv(struct sk_buff *skb) iph =ip_hdr (skb);read_lock (&ipip6_lock); -if ((tunnel =ipip6_tunnel_lookup (&init_net, +if ((tunnel =ipip6_tunnel_lookup (dev_net (skb->dev), iph->saddr, iph->daddr)) !=NULL ) {secpath_reset (skb); skb->mac_header = skb->network_header;
Signature · 1 line
1.5.3.4
PATCH 4/8 : Make the fallback tunnel device per-net
In reply to Pavel EmelyanovAllocate and register one in sit_init_net, use sitn->fb_tunnel_dev over the code and unregister one in sit_exit_net.
--- net/ipv6/sit.c | 61 ++++++++++++++++++++++++++----------------------------- 1 files changed, 29 insertions(+), 32 deletions(-)
net/ipv6/sit.c +29 -32
@@ -70,10 +70,9 @@ static void ipip6_tunnel_setup(struct net_device *dev);static int sit_net_id;struct sit_net { +struct net_device *fb_tunnel_dev; }; -static struct net_device *ipip6_fb_tunnel_dev; -static struct ip_tunnel *tunnels_r_l[HASH_SIZE ];static struct ip_tunnel *tunnels_r[HASH_SIZE ];static struct ip_tunnel *tunnels_l[HASH_SIZE ];
@@ -386,7 +385,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)struct net *net =dev_net (dev);struct sit_net *sitn =net_generic (net, sit_net_id); -if (dev == ipip6_fb_tunnel_dev) { +if (dev == sitn->fb_tunnel_dev) {write_lock_bh (&ipip6_lock); tunnels_wc[0 ] =NULL ;write_unlock_bh (&ipip6_lock);
@@ -862,7 +861,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)switch (cmd) {case SIOCGETTUNNEL : t =NULL ; -if (dev == ipip6_fb_tunnel_dev) { +if (dev == sitn->fb_tunnel_dev) {if (copy_from_user (&p, ifr->ifr_ifru.ifru_data,sizeof (p))) { err = -EFAULT ;break ;
@@ -895,7 +894,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) t =ipip6_tunnel_locate (net, &p, cmd ==SIOCADDTUNNEL ); -if (dev != ipip6_fb_tunnel_dev && cmd ==SIOCCHGTUNNEL ) { +if (dev != sitn->fb_tunnel_dev && cmd ==SIOCCHGTUNNEL ) {if (t !=NULL ) {if (t->dev != dev) { err = -EEXIST ;
@@ -940,7 +939,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)if (!capable (CAP_NET_ADMIN )) goto done; -if (dev == ipip6_fb_tunnel_dev) { +if (dev == sitn->fb_tunnel_dev) { err = -EFAULT ;if (copy_from_user (&p, ifr->ifr_ifru.ifru_data,sizeof (p))) goto done;
@@ -948,7 +947,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)if ((t =ipip6_tunnel_locate (net, &p,0 )) ==NULL ) goto done; err = -EPERM ; -if (t ==netdev_priv (ipip6_fb_tunnel_dev)) +if (t ==netdev_priv (sitn->fb_tunnel_dev)) goto done; dev = t->dev; }
@@ -964,7 +963,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)if (cmd !=SIOCGETPRL && !capable (CAP_NET_ADMIN )) goto done; err = -EINVAL ; -if (dev == ipip6_fb_tunnel_dev) +if (dev == sitn->fb_tunnel_dev) goto done; err = -EFAULT ;if (copy_from_user (&prl, ifr->ifr_ifru.ifru_data,sizeof (prl)))
@@ -1047,7 +1046,7 @@ static int ipip6_tunnel_init(struct net_device *dev)return 0 ; } -static int __init ipip6_fb_tunnel_init (struct net_device *dev) +static int ipip6_fb_tunnel_init (struct net_device *dev) {struct ip_tunnel *tunnel =netdev_priv (dev);struct iphdr *iph = &tunnel->parms.iph;
@@ -1099,8 +1098,25 @@ static int sit_init_net(struct net *net)if (err <0 ) goto err_assign; + sitn->fb_tunnel_dev =alloc_netdev (sizeof (struct ip_tunnel ),"sit0" , + ipip6_tunnel_setup); +if (!sitn->fb_tunnel_dev) { + err = -ENOMEM ; + goto err_alloc_dev; + } + + sitn->fb_tunnel_dev->init = ipip6_fb_tunnel_init; +dev_net_set (sitn->fb_tunnel_dev, net); + +if ((err =register_netdev (sitn->fb_tunnel_dev))) + goto err_reg_dev; +return 0 ; +err_reg_dev: +free_netdev (sitn->fb_tunnel_dev); +err_alloc_dev: +/* nothing */ err_assign:kfree (sitn); err_alloc:
@@ -1112,6 +1128,9 @@ static void sit_exit_net(struct net *net)struct sit_net *sitn; sitn =net_generic (net, sit_net_id); +rtnl_lock (); +unregister_netdevice (sitn->fb_tunnel_dev); +rtnl_unlock ();kfree (sitn); }
@@ -1126,7 +1145,6 @@ static void __exit sit_cleanup(void)rtnl_lock ();sit_destroy_tunnels (); -unregister_netdevice (ipip6_fb_tunnel_dev);rtnl_unlock ();unregister_pernet_gen_device (sit_net_id, &sit_net_ops);
@@ -1143,32 +1161,11 @@ static int __init sit_init(void)return -EAGAIN ; } - ipip6_fb_tunnel_dev =alloc_netdev (sizeof (struct ip_tunnel ),"sit0" , - ipip6_tunnel_setup); -if (!ipip6_fb_tunnel_dev) { - err = -ENOMEM ; - goto err1; - } - - ipip6_fb_tunnel_dev->init = ipip6_fb_tunnel_init; - -if ((err =register_netdev (ipip6_fb_tunnel_dev))) - goto err2; - err =register_pernet_gen_device (&sit_net_id, &sit_net_ops);if (err <0 ) - goto err3; +xfrm4_tunnel_deregister (&sit_handler,AF_INET6 ); - out:return err; - err2: -free_netdev (ipip6_fb_tunnel_dev); - err1: -xfrm4_tunnel_deregister (&sit_handler,AF_INET6 ); - goto out; -err3: -unregister_netdevice (ipip6_fb_tunnel_dev); - goto err1; }module_init (sit_init);
Signature · 1 line
1.5.3.4
PATCH 5/8 : Make tunnels hashes per-net.
In reply to Pavel EmelyanovJust move all the hashes on the sit_net structure and patch the rest of the code appropriately.
--- net/ipv6/sit.c | 45 +++++++++++++++++++++++++-------------------- 1 files changed, 25 insertions(+), 20 deletions(-)
net/ipv6/sit.c +25 -20
@@ -70,15 +70,15 @@ static void ipip6_tunnel_setup(struct net_device *dev);static int sit_net_id;struct sit_net { +struct ip_tunnel *tunnels_r_l[HASH_SIZE ]; +struct ip_tunnel *tunnels_r[HASH_SIZE ]; +struct ip_tunnel *tunnels_l[HASH_SIZE ]; +struct ip_tunnel *tunnels_wc[1 ]; +struct ip_tunnel **tunnels[4 ]; +struct net_device *fb_tunnel_dev; }; -static struct ip_tunnel *tunnels_r_l[HASH_SIZE ]; -static struct ip_tunnel *tunnels_r[HASH_SIZE ]; -static struct ip_tunnel *tunnels_l[HASH_SIZE ]; -static struct ip_tunnel *tunnels_wc[1 ]; -static struct ip_tunnel **tunnels[4 ] = { tunnels_wc, tunnels_l, tunnels_r, tunnels_r_l }; -static DEFINE_RWLOCK (ipip6_lock); static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
@@ -87,21 +87,22 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,unsigned h0 =HASH (remote);unsigned h1 =HASH (local);struct ip_tunnel *t; +struct sit_net *sitn =net_generic (net, sit_net_id); -for (t = tunnels_r_l[h0^h1]; t; t = t->next) { +for (t = sitn->tunnels_r_l[h0^h1]; t; t = t->next) {if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP ))return t; } -for (t = tunnels_r[h0]; t; t = t->next) { +for (t = sitn->tunnels_r[h0]; t; t = t->next) {if (remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP ))return t; } -for (t = tunnels_l[h1]; t; t = t->next) { +for (t = sitn->tunnels_l[h1]; t; t = t->next) {if (local == t->parms.iph.saddr && (t->dev->flags&IFF_UP ))return t; } -if ((t = tunnels_wc[0 ]) !=NULL && (t->dev->flags&IFF_UP )) +if ((t = sitn->tunnels_wc[0 ]) !=NULL && (t->dev->flags&IFF_UP ))return t;return NULL ; }
@@ -122,7 +123,7 @@ static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn, prio |=1 ; h ^=HASH (local); } -return &tunnels[prio][h]; +return &sitn->tunnels[prio][h]; } static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn,
@@ -387,7 +388,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)if (dev == sitn->fb_tunnel_dev) {write_lock_bh (&ipip6_lock); - tunnels_wc[0 ] =NULL ; + sitn->tunnels_wc[0 ] =NULL ;write_unlock_bh (&ipip6_lock);dev_put (dev); }else {
@@ -1050,6 +1051,8 @@ static int ipip6_fb_tunnel_init(struct net_device *dev) {struct ip_tunnel *tunnel =netdev_priv (dev);struct iphdr *iph = &tunnel->parms.iph; +struct net *net =dev_net (dev); +struct sit_net *sitn =net_generic (net, sit_net_id); tunnel->dev = dev;strcpy (tunnel->parms.name, dev->name);
@@ -1060,7 +1063,7 @@ static int ipip6_fb_tunnel_init(struct net_device *dev) iph->ttl =64 ;dev_hold (dev); - tunnels_wc[0 ] = tunnel; + sitn->tunnels_wc[0 ] = tunnel;return 0 ; }
@@ -1070,7 +1073,7 @@ static struct xfrm_tunnel sit_handler = { .priority = 1, }; -static void __exit sit_destroy_tunnels(void) +static void sit_destroy_tunnels (struct sit_net *sitn) {int prio;
@@ -1078,7 +1081,7 @@ static void __exit sit_destroy_tunnels(void)int h;for (h =0 ; h <HASH_SIZE ; h++) {struct ip_tunnel *t; -while ((t = tunnels[prio][h]) !=NULL ) +while ((t = sitn->tunnels[prio][h]) !=NULL )unregister_netdevice (t->dev); } }
@@ -1090,7 +1093,7 @@ static int sit_init_net(struct net *net)struct sit_net *sitn; err = -ENOMEM ; - sitn =kmalloc (sizeof (struct sit_net ),GFP_KERNEL ); + sitn =kzalloc (sizeof (struct sit_net ),GFP_KERNEL );if (sitn ==NULL ) goto err_alloc;
@@ -1098,6 +1101,11 @@ static int sit_init_net(struct net *net)if (err <0 ) goto err_assign; + sitn->tunnels[0 ] = sitn->tunnels_wc; + sitn->tunnels[1 ] = sitn->tunnels_l; + sitn->tunnels[2 ] = sitn->tunnels_r; + sitn->tunnels[3 ] = sitn->tunnels_r_l; + sitn->fb_tunnel_dev =alloc_netdev (sizeof (struct ip_tunnel ),"sit0" , ipip6_tunnel_setup);if (!sitn->fb_tunnel_dev) {
@@ -1129,6 +1137,7 @@ static void sit_exit_net(struct net *net) sitn =net_generic (net, sit_net_id);rtnl_lock (); +sit_destroy_tunnels (sitn);unregister_netdevice (sitn->fb_tunnel_dev);rtnl_unlock ();kfree (sitn);
@@ -1143,10 +1152,6 @@ static void __exit sit_cleanup(void) {xfrm4_tunnel_deregister (&sit_handler,AF_INET6 ); -rtnl_lock (); -sit_destroy_tunnels (); -rtnl_unlock (); -unregister_pernet_gen_device (sit_net_id, &sit_net_ops); }
Signature · 1 line
1.5.3.4
PATCH 6/8 : Use proper net in routing calls.
In reply to Pavel EmelyanovI.e. replace init_net stubs in ip_route_output_key() calls.
--- net/ipv6/sit.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-)
net/ipv6/sit.c +6 -5
@@ -527,11 +527,12 @@ out:skb_reset_network_header (skb2);/* Try to guess incoming interface */ - rt6i =rt6_lookup (&init_net, &iph6->saddr,NULL ,NULL ,0 ); + rt6i =rt6_lookup (dev_net (skb->dev), &iph6->saddr,NULL ,NULL ,0 );if (rt6i && rt6i->rt6i_dev) { skb2->dev = rt6i->rt6i_dev; - rt6i =rt6_lookup (&init_net, &iph6->daddr, &iph6->saddr,NULL ,0 ); + rt6i =rt6_lookup (dev_net (skb->dev), + &iph6->daddr, &iph6->saddr,NULL ,0 );if (rt6i && rt6i->rt6i_dev && rt6i->rt6i_dev->type ==ARPHRD_SIT ) {struct ip_tunnel *t =netdev_priv (rt6i->rt6i_dev);
@@ -701,7 +702,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) .tos = RT_TOS(tos) } }, .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; -if (ip_route_output_key (&init_net, &rt, &fl)) { +if (ip_route_output_key (dev_net (dev), &rt, &fl)) { tunnel->stat.tx_carrier_errors++; goto tx_error_icmp; }
@@ -830,7 +831,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 };struct rtable *rt; -if (!ip_route_output_key (&init_net, &rt, &fl)) { +if (!ip_route_output_key (dev_net (dev), &rt, &fl)) { tdev = rt->u.dst.dev;ip_rt_put (rt); }
@@ -838,7 +839,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) }if (!tdev && tunnel->parms.link) - tdev =__dev_get_by_index (&init_net, tunnel->parms.link); + tdev =__dev_get_by_index (dev_net (dev), tunnel->parms.link);if (tdev) { dev->hard_header_len = tdev->hard_header_len +sizeof (struct iphdr );
Signature · 1 line
1.5.3.4
PATCH 7/8 : Allow to create SIT tunnels in net namespaces.
In reply to Pavel EmelyanovSet proper net and mark a new device as NETNS_LOCAL before registering.
--- net/ipv6/sit.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
net/ipv6/sit.c +3 -0
@@ -182,6 +182,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,if (dev ==NULL )return NULL ; +dev_net_set (dev, net); +if (strchr (name,'%' )) {if (dev_alloc_name (dev, name) <0 ) goto failed_free;
@@ -1029,6 +1031,7 @@ static void ipip6_tunnel_setup(struct net_device *dev) dev->flags =IFF_NOARP ; dev->iflink =0 ; dev->addr_len =4 ; + dev->features |=NETIF_F_NETNS_LOCAL ; }static int ipip6_tunnel_init (struct net_device *dev)
Signature · 1 line
1.5.3.4
PATCH 8/8 : Allow for IPPROTO_IPV6 protocol in namespaces.
In reply to Pavel EmelyanovThis makes sit-generated traffic enter the namespace.
--- net/ipv4/tunnel4.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
net/ipv4/tunnel4.c +1 -0
@@ -144,6 +144,7 @@ static struct net_protocol tunnel64_protocol = { .handler = tunnel64_rcv, .err_handler = tunnel64_err, .no_policy = 1, + .netns_ok = 1, };#endif
Signature · 1 line
1.5.3.4
David Miller
maintainerFrom: Pavel Emelyanov <[email protected]>
Date: Tue, 15 Apr 2008 17:26:18 +0400
Quoted 3 lines
ipv4 tunnels are done - time to virtualize ipv6 tunnels.
Signed-off-by Pavel Emelyanov <[email protected]>
Applied and pushed to net-2.6.26