I plan to commit this soon as part of the mrouting cleanup.
Bring the IPv4 multicast forwarding code more into line with the IPv6 version, by unconditionally building with PIM support enabled, and allowing it to be built as a loadable module.
Use encap_attach_func() to hookup the IPPROTO_PIM input path. Keep the reserved identifier _PIM_VT around as some folks use this. TODO: Make the IPv6 multicast forwarding code dynamically loadable. Index: sys/conf/NOTES =================================================================== RCS file: /home/ncvs/src/sys/conf/NOTES,v retrieving revision 1.1409 diff -u -p -r1.1409 NOTES --- sys/conf/NOTES 7 Feb 2007 18:55:29 -0000 1.1409 +++ sys/conf/NOTES 9 Feb 2007 01:59:43 -0000 @@ -807,10 +807,7 @@ device stf #6to4 IPv6 over IPv4 encap # Internet family options: # # MROUTING enables the kernel multicast packet forwarder, which works -# with mrouted(8). -# -# PIM enables Protocol Independent Multicast in the kernel. -# Requires MROUTING enabled. +# with mrouted and XORP. # # IPFIREWALL enables support for IP firewall construction, in # conjunction with the `ipfw' program. IPFIREWALL_VERBOSE sends @@ -854,7 +851,6 @@ device stf #6to4 IPv6 over IPv4 encap # using the trpt(8) utility. # options MROUTING # Multicast routing -options PIM # Protocol Independent Multicast options IPFIREWALL #firewall options IPFIREWALL_VERBOSE #enable logging to syslogd(8) options IPFIREWALL_VERBOSE_LIMIT=100 #limit verbosity Index: sys/conf/options =================================================================== RCS file: /home/ncvs/src/sys/conf/options,v retrieving revision 1.575 diff -u -p -r1.575 options --- sys/conf/options 7 Feb 2007 18:55:29 -0000 1.575 +++ sys/conf/options 9 Feb 2007 01:59:43 -0000 @@ -352,7 +352,6 @@ ETHER_8023 opt_ef.h ETHER_8022 opt_ef.h ETHER_SNAP opt_ef.h MROUTING opt_mrouting.h -PIM opt_mrouting.h INET opt_inet.h INET6 opt_inet6.h IPSEC opt_ipsec.h Index: sys/netinet/in_proto.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/in_proto.c,v retrieving revision 1.82 diff -u -p -r1.82 in_proto.c --- sys/netinet/in_proto.c 3 Nov 2006 15:23:14 -0000 1.82 +++ sys/netinet/in_proto.c 9 Feb 2007 01:59:43 -0000 @@ -56,9 +56,6 @@ #include <netinet/ip_var.h> #include <netinet/ip_icmp.h> #include <netinet/igmp_var.h> -#ifdef PIM -#include <netinet/pim_var.h> -#endif #include <netinet/tcp.h> #include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> @@ -345,17 +342,6 @@ struct protosw inetsw[] = { .pr_usrreqs = &rip_usrreqs }, #endif -#ifdef PIM -{ - .pr_type = SOCK_RAW, - .pr_domain = &inetdomain, - .pr_protocol = IPPROTO_PIM, - .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, - .pr_input = pim_input, - .pr_ctloutput = rip_ctloutput, - .pr_usrreqs = &rip_usrreqs -}, -#endif /* PIM */ #ifdef DEV_PFSYNC { .pr_type = SOCK_RAW, @@ -438,9 +424,6 @@ SYSCTL_NODE(_net_inet, IPPROTO_AH, ipsec #endif /* IPSEC */ #endif /* !FAST_IPSEC */ SYSCTL_NODE(_net_inet, IPPROTO_RAW, raw, CTLFLAG_RW, 0, "RAW"); -#ifdef PIM -SYSCTL_NODE(_net_inet, IPPROTO_PIM, pim, CTLFLAG_RW, 0, "PIM"); -#endif #ifdef DEV_PFSYNC SYSCTL_NODE(_net_inet, IPPROTO_PFSYNC, pfsync, CTLFLAG_RW, 0, "PFSYNC"); #endif Index: sys/netinet/ip_mroute.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/ip_mroute.c,v retrieving revision 1.126 diff -u -p -r1.126 ip_mroute.c --- sys/netinet/ip_mroute.c 8 Feb 2007 23:05:08 -0000 1.126 +++ sys/netinet/ip_mroute.c 9 Feb 2007 01:59:45 -0000 @@ -58,9 +58,7 @@ #include "opt_mac.h" #include "opt_mrouting.h" -#ifdef PIM #define _PIM_VT 1 -#endif #include <sys/param.h> #include <sys/kernel.h> @@ -91,10 +89,8 @@ #include <netinet/ip_mroute.h> #include <netinet/ip_var.h> #include <netinet/ip_options.h> -#ifdef PIM #include <netinet/pim.h> #include <netinet/pim_var.h> -#endif #include <netinet/udp.h> #include <machine/in_cksum.h> @@ -197,12 +193,27 @@ static u_int bw_upcalls_n; /* # of pendi static struct callout bw_upcalls_ch; #define BW_UPCALLS_PERIOD (hz) /* periodical flush of bw upcalls */ -#ifdef PIM static struct pimstat pimstat; + +SYSCTL_NODE(_net_inet, IPPROTO_PIM, pim, CTLFLAG_RW, 0, "PIM"); SYSCTL_STRUCT(_net_inet_pim, PIMCTL_STATS, stats, CTLFLAG_RD, &pimstat, pimstat, "PIM Statistics (struct pimstat, netinet/pim_var.h)"); +extern struct domain inetdomain; +struct protosw in_pim_protosw = { + .pr_type = SOCK_RAW, + .pr_domain = &inetdomain, + .pr_protocol = IPPROTO_PIM, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_LASTHDR, + .pr_input = pim_input, + .pr_output = (pr_output_t*)rip_output, + .pr_ctloutput = rip_ctloutput, + .pr_usrreqs = &rip_usrreqs +}; +static const struct encaptab *pim_encap_cookie; +static int pim_encapcheck(const struct mbuf *, int, int, void *); + /* * Note: the PIM Register encapsulation adds the following in front of a * data packet: @@ -247,7 +258,6 @@ static struct pim_encap_pimhdr pim_encap static struct ifnet multicast_register_if; static vifi_t reg_vif_num = VIFI_INVALID; -#endif /* PIM */ /* * Private variables. @@ -296,7 +306,6 @@ static void bw_meter_process(void); static void expire_bw_upcalls_send(void *); static void expire_bw_meter_process(void *); -#ifdef PIM static int pim_register_send(struct ip *, struct vif *, struct mbuf *, struct mfc *); static int pim_register_send_rp(struct ip *, struct vif *, @@ -304,7 +313,6 @@ static int pim_register_send_rp(struct i static int pim_register_send_upcall(struct ip *, struct vif *, struct mbuf *, struct mfc *); static struct mbuf *pim_register_prepare(struct ip *, struct mbuf *); -#endif /* * whether or not special PIM assert processing is enabled. @@ -603,7 +611,7 @@ ip_mrouter_reset(void) callout_init(&bw_meter_ch, NET_CALLOUT_MPSAFE); } -static struct mtx mrouter_mtx; /* used to synch init/done work */ +static struct mtx mrouter_mtx; static void if_detached_event(void *arg __unused, struct ifnet *ifp) @@ -788,9 +796,7 @@ X_ip_mrouter_done(void) bzero(bw_meter_timers, sizeof(bw_meter_timers)); MFC_UNLOCK(); -#ifdef PIM reg_vif_num = VIFI_INVALID; -#endif mtx_unlock(&mrouter_mtx); @@ -883,7 +889,6 @@ add_vif(struct vifctl *vifcp) } /* Find the interface with an address in AF_INET family */ -#ifdef PIM if (vifcp->vifc_flags & VIFF_REGISTER) { /* * XXX: Because VIFF_REGISTER does not really need a valid @@ -891,9 +896,7 @@ add_vif(struct vifctl *vifcp) * check its address. */ ifp = NULL; - } else -#endif - { + } else { sin.sin_addr = vifcp->vifc_lcl_addr; ifa = ifa_ifwithaddr((struct sockaddr *)&sin); if (ifa == NULL) { @@ -907,7 +910,6 @@ add_vif(struct vifctl *vifcp) log(LOG_ERR, "tunnels are no longer supported\n"); VIF_UNLOCK(); return EOPNOTSUPP; -#ifdef PIM } else if (vifcp->vifc_flags & VIFF_REGISTER) { ifp = &multicast_register_if; if (mrtdebug) @@ -918,7 +920,6 @@ add_vif(struct vifctl *vifcp) multicast_register_if.if_flags = IFF_LOOPBACK; reg_vif_num = vifcp->vifc_vifi; } -#endif } else { /* Make sure the interface supports multicast */ if ((ifp->if_flags & IFF_MULTICAST) == 0) { VIF_UNLOCK(); @@ -984,10 +985,8 @@ del_vif_locked(vifi_t vifi) if (!(vifp->v_flags & (VIFF_TUNNEL | VIFF_REGISTER))) if_allmulti(vifp->v_ifp, 0); -#ifdef PIM if (vifp->v_flags & VIFF_REGISTER) reg_vif_num = VIFI_INVALID; -#endif bzero((caddr_t)vifp, sizeof (*vifp)); @@ -1571,12 +1570,10 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp * (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.) */ if (xmt_vif < numvifs) { -#ifdef PIM if (viftable[xmt_vif].v_flags & VIFF_REGISTER) - pim_register_send(ip, viftable + xmt_vif, m, rt); + pim_register_send(ip, viftable + xmt_vif, m, rt); else -#endif - phyint_send(ip, viftable + xmt_vif, m); + phyint_send(ip, viftable + xmt_vif, m); return 1; } @@ -1603,10 +1600,8 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp struct timeval now; u_long delta; -#ifdef PIM if (ifp == &multicast_register_if) pimstat.pims_rcv_registers_wrongiif++; -#endif /* Get vifi for the incoming packet */ for (vifi=0; vifi < numvifs && viftable[vifi].v_ifp != ifp; vifi++) @@ -1674,12 +1669,10 @@ ip_mdq(struct mbuf *m, struct ifnet *ifp if ((rt->mfc_ttls[vifi] > 0) && (ip->ip_ttl > rt->mfc_ttls[vifi])) { viftable[vifi].v_pkt_out++; viftable[vifi].v_bytes_out += plen; -#ifdef PIM if (viftable[vifi].v_flags & VIFF_REGISTER) pim_register_send(ip, viftable + vifi, m, rt); else -#endif - phyint_send(ip, viftable + vifi, m); + phyint_send(ip, viftable + vifi, m); } /* @@ -2516,7 +2509,6 @@ expire_bw_meter_process(void *unused) * End of bandwidth monitoring code */ -#ifdef PIM /* * Send the packet up to the user daemon, or eventually do kernel encapsulation * @@ -2739,6 +2731,21 @@ pim_register_send_rp(struct ip *ip, stru * (used by PIM-SM): the PIM header is stripped off, and the inner packet * is passed to if_simloop(). */ +static int +pim_encapcheck(const struct mbuf *m, int off, int proto, void *arg) +{ + struct ip *ip = mtod(m, struct ip *); + int hlen = ip->ip_hl << 2; + +#ifdef DIAGNOSTIC + KASSERT(proto == IPPROTO_PIM, ("not for IPPROTO_PIM")); +#endif + if (!IN_MULTICAST(ntohl(((struct ip *)((char *)ip+hlen))->ip_dst.s_addr))) + return 0; + + return 64; +} + void pim_input(struct mbuf *m, int off) { @@ -2971,7 +2978,6 @@ pim_input_to_daemon: return; } -#endif /* PIM */ static int ip_mroute_modevent(module_t mod, int type, void *unused) @@ -2982,6 +2988,15 @@ ip_mroute_modevent(module_t mod, int typ MFC_LOCK_INIT(); VIF_LOCK_INIT(); ip_mrouter_reset(); + pim_encap_cookie = encap_attach_func(AF_INET, IPPROTO_PIM, + pim_encapcheck, &in_pim_protosw, NULL); + if (pim_encap_cookie == NULL) { + printf("ip_mroute: unable to attach pim encap\n"); + VIF_LOCK_DESTROY(); + MFC_LOCK_DESTROY(); + mtx_destroy(&mrouter_mtx); + return (EINVAL); + } ip_mcast_src = X_ip_mcast_src; ip_mforward = X_ip_mforward; ip_mrouter_done = X_ip_mrouter_done; @@ -3006,6 +3021,11 @@ ip_mroute_modevent(module_t mod, int typ if (ip_mrouter) return EINVAL; + if (pim_encap_cookie) { + encap_detach(pim_encap_cookie); + pim_encap_cookie = NULL; + } + X_ip_mrouter_done(); ip_mcast_src = NULL; ip_mforward = NULL;
_______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "[EMAIL PROTECTED]"