MFp4 CH=183052 183053 183258:

In protosw we define pr_protocol as short, while on the wire
  it is an uint8_t.  That way we can have "internal" protocols
  like DIVERT, SEND or gaps for modules (PROTO_SPACER).
  Switch ipproto_{un,}register to accept a short protocol number(*)
  and do an upfront check for valid boundries. With this we
  also consistently report EPROTONOSUPPORT for out of bounds
  protocols, as we did for proto == 0.  This allows a caller
  to not error for this case, which is especially important
  if we want to automatically call these from domain handling.

  (*) the functions have been without any in-tree consumer
  since the initial introducation, so this is considered save.

  Implement ip6proto_{un,}register() similarly to their legacy IP
  counter parts to allow modules to hook up dynamically.

Reviewed by:	philip, will
MFC after:	1 week
This commit is contained in:
Bjoern A. Zeeb 2010-09-02 17:43:44 +00:00
parent 90017de999
commit 1b48d24533
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=212155
4 changed files with 69 additions and 12 deletions

View File

@ -1287,12 +1287,12 @@ ip_drain(void)
* in inetsw[], either statically or through pf_proto_register().
*/
int
ipproto_register(u_char ipproto)
ipproto_register(short ipproto)
{
struct protosw *pr;
/* Sanity checks. */
if (ipproto == 0)
if (ipproto <= 0 || ipproto >= IPPROTO_MAX)
return (EPROTONOSUPPORT);
/*
@ -1310,24 +1310,20 @@ ipproto_register(u_char ipproto)
pr < inetdomain.dom_protoswNPROTOSW; pr++) {
if (pr->pr_domain->dom_family == PF_INET &&
pr->pr_protocol && pr->pr_protocol == ipproto) {
/* Be careful to only index valid IP protocols. */
if (pr->pr_protocol < IPPROTO_MAX) {
ip_protox[pr->pr_protocol] = pr - inetsw;
return (0);
} else
return (EINVAL);
ip_protox[pr->pr_protocol] = pr - inetsw;
return (0);
}
}
return (EPROTONOSUPPORT);
}
int
ipproto_unregister(u_char ipproto)
ipproto_unregister(short ipproto)
{
struct protosw *pr;
/* Sanity checks. */
if (ipproto == 0)
if (ipproto <= 0 || ipproto >= IPPROTO_MAX)
return (EPROTONOSUPPORT);
/* Check if the protocol was indeed registered. */

View File

@ -220,8 +220,8 @@ extern int
int ip_output(struct mbuf *,
struct mbuf *, struct route *, int, struct ip_moptions *,
struct inpcb *);
int ipproto_register(u_char);
int ipproto_unregister(u_char);
int ipproto_register(short);
int ipproto_unregister(short);
struct mbuf *
ip_reass(struct mbuf *);
struct in_ifaddr *

View File

@ -227,6 +227,64 @@ ip6_init(void)
netisr_register(&ip6_nh);
}
/*
* The protocol to be inserted into ip6_protox[] must be already registered
* in inet6sw[], either statically or through pf_proto_register().
*/
int
ip6proto_register(short ip6proto)
{
struct ip6protosw *pr;
/* Sanity checks. */
if (ip6proto <= 0 || ip6proto >= IPPROTO_MAX)
return (EPROTONOSUPPORT);
/*
* The protocol slot must not be occupied by another protocol
* already. An index pointing to IPPROTO_RAW is unused.
*/
pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
if (pr == NULL)
return (EPFNOSUPPORT);
if (ip6_protox[ip6proto] != pr - inet6sw) /* IPPROTO_RAW */
return (EEXIST);
/*
* Find the protocol position in inet6sw[] and set the index.
*/
for (pr = (struct ip6protosw *)inet6domain.dom_protosw;
pr < (struct ip6protosw *)inet6domain.dom_protoswNPROTOSW; pr++) {
if (pr->pr_domain->dom_family == PF_INET6 &&
pr->pr_protocol && pr->pr_protocol == ip6proto) {
ip6_protox[pr->pr_protocol] = pr - inet6sw;
return (0);
}
}
return (EPROTONOSUPPORT);
}
int
ip6proto_unregister(short ip6proto)
{
struct ip6protosw *pr;
/* Sanity checks. */
if (ip6proto <= 0 || ip6proto >= IPPROTO_MAX)
return (EPROTONOSUPPORT);
/* Check if the protocol was indeed registered. */
pr = (struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
if (pr == NULL)
return (EPFNOSUPPORT);
if (ip6_protox[ip6proto] == pr - inet6sw) /* IPPROTO_RAW */
return (ENOENT);
/* Reset the protocol slot to IPPROTO_RAW. */
ip6_protox[ip6proto] = pr - inet6sw;
return (0);
}
#ifdef VIMAGE
void
ip6_destroy()

View File

@ -368,6 +368,9 @@ void ip6_init __P((void));
#ifdef VIMAGE
void ip6_destroy __P((void));
#endif
int ip6proto_register(short);
int ip6proto_unregister(short);
void ip6_input __P((struct mbuf *));
struct in6_ifaddr *ip6_getdstifaddr __P((struct mbuf *));
void ip6_freepcbopts __P((struct ip6_pktopts *));