Date: Fri, 09 Feb 2007 03:37:00 +0000 From: Bruce M Simpson <bms@incunabulum.net> To: freebsd-net@freebsd.org Subject: [PATCH] make netinet MROUTING dynamically loadable with PIM Message-ID: <45CBEC5C.4060900@incunabulum.net>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------070503090209060701040608 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit I plan to commit this soon as part of the mrouting cleanup. --------------070503090209060701040608 Content-Type: text/x-patch; name="ipv4-pim-module.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ipv4-pim-module.diff" 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; --------------070503090209060701040608--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?45CBEC5C.4060900>