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:
parent
90017de999
commit
1b48d24533
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=212155
@ -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. */
|
||||
|
@ -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 *
|
||||
|
@ -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()
|
||||
|
@ -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 *));
|
||||
|
Loading…
Reference in New Issue
Block a user