diff -ur linux-2.6.1/include/linux/mroute.h linux-2.6.1-mr/include/linux/mroute.h --- linux-2.6.1/include/linux/mroute.h Fri Jan 9 07:59:34 2004 +++ linux-2.6.1-mr/include/linux/mroute.h Sat Jan 17 18:49:00 2004 @@ -60,6 +60,16 @@ struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */ }; +struct vifctln { + vifi_t vifc_vifi; /* Index of VIF */ + unsigned char vifc_flags; /* VIFF_ flags */ + unsigned char vifc_threshold; /* ttl limit */ + unsigned int vifc_rate_limit; /* Rate limiter values (NI) */ + struct in_addr vifc_lcl_addr; /* Our address */ + struct in_addr vifc_rmt_addr; /* IPIP tunnel addr */ + int vifc_ifindex; /* Index of real Interface */ +}; + #define VIFF_TUNNEL 0x1 /* IPIP tunnel */ #define VIFF_SRCRT 0x2 /* NI */ #define VIFF_REGISTER 0x4 /* register vif */ diff -ur linux-2.6.1/net/ipv4/ipmr.c linux-2.6.1-mr/net/ipv4/ipmr.c --- linux-2.6.1/net/ipv4/ipmr.c Fri Jan 9 07:59:33 2004 +++ linux-2.6.1-mr/net/ipv4/ipmr.c Sat Jan 17 19:50:14 2004 @@ -116,7 +116,7 @@ /* Service routines creating virtual interfaces: DVMRP tunnels and PIMREG */ static -struct net_device *ipmr_new_tunnel(struct vifctl *v) +struct net_device *ipmr_new_tunnel(struct vifctln *v) { struct net_device *dev; @@ -130,6 +130,7 @@ struct in_device *in_dev; memset(&p, 0, sizeof(p)); + p.link = v->vifc_ifindex; p.iph.daddr = v->vifc_rmt_addr.s_addr; p.iph.saddr = v->vifc_lcl_addr.s_addr; p.iph.version = 4; @@ -373,7 +374,7 @@ } } -static int vif_add(struct vifctl *vifc, int mrtsock) +static int vif_add(struct vifctln *vifc, int mrtsock) { int vifi = vifc->vifc_vifi; struct vif_device *v = &vif_table[vifi]; @@ -404,7 +405,9 @@ return -ENOBUFS; break; case 0: - dev=ip_dev_find(vifc->vifc_lcl_addr.s_addr); + dev=vifc->vifc_ifindex + ?dev_get_by_index(vifc->vifc_ifindex) + :ip_dev_find(vifc->vifc_lcl_addr.s_addr); if (!dev) return -EADDRNOTAVAIL; __dev_put(dev); @@ -844,7 +847,7 @@ int ip_mroute_setsockopt(struct sock *sk,int optname,char *optval,int optlen) { int ret; - struct vifctl vif; + struct vifctln vif; struct mfcctl mfc; if(optname!=MRT_INIT) @@ -884,9 +887,10 @@ return ip_ra_control(sk, 0, NULL); case MRT_ADD_VIF: case MRT_DEL_VIF: - if(optlen!=sizeof(vif)) + if(optlen!=sizeof(vif) && optlen!=sizeof(struct vifctl)) return -EINVAL; - if (copy_from_user(&vif,optval,sizeof(vif))) + vif.vifc_ifindex = 0; + if (copy_from_user(&vif,optval,optlen)) return -EFAULT; if(vif.vifc_vifi >= MAXVIFS) return -ENFILE;