PERFORCE change 167260 for review
Marko Zec
zec at freebsd.org
Thu Aug 13 00:36:17 UTC 2009
On Thursday 13 August 2009 02:22:22 Julian Elischer wrote:
> Marko Zec wrote:
> > On Thursday 13 August 2009 00:44:49 Julian Elischer wrote:
> >> Marko Zec wrote:
> >>> On Wednesday 12 August 2009 23:58:46 Julian Elischer wrote:
> >>>> Marko Zec wrote:
> >>>
> >>> ...
> >>>
> >>>>> @@ -710,22 +715,36 @@
> >>>>> .pr_input = div_input,
> >>>>> .pr_ctlinput = div_ctlinput,
> >>>>> .pr_ctloutput = ip_ctloutput,
> >>>>> - .pr_init = NULL,
> >>>>> + .pr_init = div_init,
> >>>>> .pr_usrreqs = &div_usrreqs
> >>>>
> >>>> If you are going to make pr_init() called for every vnet then
> >>>> pr_destroy should be as well. But in fact that is not really safe.
> >>>> (either of them)
> >>>>
> >>>> The trouble is that we can not guarantee that other protocols can
> >>>> handle being called multiple times in their init and destroy methods.
> >>>> Especially 3rd party protocols.
> >>>>
> >>>> We need to ensure only protocols that have been converted to run
> >>>> with multiple vnets are ever called with multiple vnets.
> >>>>
> >>>> for this reason the only safe way to do this is via the VNET_SYSINIT
> >>>> and VNET_SYSUNINIT calls.
> >>>
> >>> That would mean you would have to convert most if not all of the
> >>> existing things that hang off of protosw-s in netinet, netinet6 etc. to
> >>> use VNET_SYSINT / VNET_SYSUNIT instead of protosw->pr_init(). So the
> >>> short answer is no.
> >>
> >> robert has done just that.
> >
> > hmm:
> >
> > tpx32% pwd
> > /u/marko/svn/head/sys
> >
> > tpx32% fgrep -R .pr_init netinet netinet6 netipsec|fgrep -v .svn
> > netinet/ip_divert.c: .pr_init = div_init,
> > netinet/in_proto.c: .pr_init = ip_init,
> > netinet/in_proto.c: .pr_init = udp_init,
> > netinet/in_proto.c: .pr_init = tcp_init,
> > netinet/in_proto.c: .pr_init = sctp_init,
> > netinet/in_proto.c: .pr_init = icmp_init,
> > netinet/in_proto.c: .pr_init = encap_init,
> > netinet/in_proto.c: .pr_init = encap_init,
> > netinet/in_proto.c: .pr_init = encap_init,
> > netinet/in_proto.c: .pr_init = encap_init,
> > netinet/in_proto.c: .pr_init = encap_init,
> > netinet/in_proto.c: .pr_init = rip_init,
> > netinet6/in6_proto.c: .pr_init = ip6_init,
> > netinet6/in6_proto.c: .pr_init = tcp_init,
> > netinet6/in6_proto.c: .pr_init = icmp6_init,
> > netinet6/in6_proto.c: .pr_init = encap_init,
> > netinet6/in6_proto.c: .pr_init = encap_init,
> > netinet6/ip6_mroute.c: .pr_init = pim6_init,
> > netipsec/keysock.c: .pr_init = raw_init,
>
> AND for example:
> in ./netinet/in_proto.c
> VNET_DOMAIN_SET(inet);
> includes
> VNET_SYSINIT ##### --> called for every vnet as created ####
> calls
> vnet_domain_init()
> calls
> domain_init()
> calls
> protosw_init()
> which includes
> if (pr->pr_init)
> (*pr->pr_init)();
>
> so, robert is calling the init routine from each protocol
> not the modevent.
Right.
But when we kldload ipdivert and register its protosw via pf_proto_register(),
VNET_DOMAIN_SET() will not call ipdivert's pr_init() routine for each
existing vnet, hence pf_proto_register() will have to do this.
For subsequently created vnets, i.e. after ipdivert has been kldloaded,
pr_init() will indeed be called via VNET_DOMAIN_SET() mechanism on each vnet
instantiation. But at that point in time pf_proto_register() will not be
called. So, in both cases pr_init() will be called exactly once per vnet,
but via different mechanisms.
Marko
More information about the p4-projects
mailing list