diff -ur old/sys/netinet/ip_mroute.c new/sys/netinet/ip_mroute.c --- old/sys/netinet/ip_mroute.c Sat Oct 9 17:12:04 2004 +++ new/sys/netinet/ip_mroute.c Wed May 31 14:57:04 2006 @@ -393,7 +393,7 @@ { int error, optval; vifi_t vifi; - struct vifctl vifc; + struct vifctln vifc; struct mfcctl2 mfc; struct bw_upcall bw_upcall; uint32_t i; @@ -415,10 +415,10 @@ break; case MRT_ADD_VIF: - error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc); + error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof struct vifctl); if (error) break; - error = add_vif(&vifc); + error = add_vif(&vifc, sopt->sopt_valsize); break; case MRT_DEL_VIF: @@ -899,7 +899,7 @@ * Add a vif to the vif table */ static int -add_vif(struct vifctl *vifcp) +add_vif(struct vifctln *vifcp, size_t vifcpsize) { struct vif *vifp = viftable + vifcp->vifc_vifi; struct sockaddr_in sin = {sizeof sin, AF_INET}; @@ -934,13 +934,25 @@ } else #endif { - sin.sin_addr = vifcp->vifc_lcl_addr; - ifa = ifa_ifwithaddr((struct sockaddr *)&sin); - if (ifa == NULL) { - VIF_UNLOCK(); - return EADDRNOTAVAIL; + if (vifcpsize < sizeof struct vifctln || vifcp->vifc_ifindex <= 0) { + sin.sin_addr = vifcp->vifc_lcl_addr; + ifa = ifa_ifwithaddr((struct sockaddr *)&sin); + if (ifa == NULL) { + VIF_UNLOCK(); + return EADDRNOTAVAIL; + } + ifp = ifa->ifa_ifp; + } else { + if (vifcp->vifc_ifindex > if_index) { + VIF_UNLOCK(); + return ENXIO; + } + ifp = ifnet_byindex(vifcp->vifc_ifindex); + if (ifp == NULL) { + VIF_UNLOCK(); + return ENXIO; + } } - ifp = ifa->ifa_ifp; } if (vifcp->vifc_flags & VIFF_TUNNEL) { diff -ur old/sys/netinet/ip_mroute.h new/sys/netinet/ip_mroute.h --- old/sys/netinet/ip_mroute.h Tue Feb 1 00:26:36 2005 +++ new/sys/netinet/ip_mroute.h Wed May 31 15:02:56 2006 @@ -102,6 +102,14 @@ struct in_addr vifc_rmt_addr; /* remote address (tunnels only) */ }; +/* + * extended vifctl with interface index. + */ +struct vifctln { + struct vifctl; /* inherit vifctl fields */ + int vifc_ifindex; /* interface index */ +}; + #define VIFF_TUNNEL 0x1 /* vif represents a tunnel end-point */ #define VIFF_SRCRT 0x2 /* tunnel uses IP source routing */ #define VIFF_REGISTER 0x4 /* used for PIM Register encap/decap */