summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2004-10-19 15:45:57 +0000
committerandre <andre@FreeBSD.org>2004-10-19 15:45:57 +0000
commit00d43f4bd8218e12e456cef93e786e0a910ba560 (patch)
tree5e1381e3fd7b17aca48188a8e5c4717260ca205f /sys/netinet
parent8112f95a8c58a972c772b025bf4229fb1623a162 (diff)
downloadFreeBSD-src-00d43f4bd8218e12e456cef93e786e0a910ba560.zip
FreeBSD-src-00d43f4bd8218e12e456cef93e786e0a910ba560.tar.gz
Support for dynamically loadable and unloadable IP protocols in the ipmux.
With pr_proto_register() it has become possible to dynamically load protocols within the PF_INET domain. However the PF_INET domain has a second important structure called ip_protox[] that is derived from the 'struct protosw inetsw[]' and takes care of the de-multiplexing of the various protocols that ride on top of IP packets. The functions ipproto_[un]register() allow to dynamically adjust the ip_protox[] array mux in a consistent and easy way. To register a protocol within ip_protox[] the existence of a corresponding and matching protocol definition in inetsw[] is required. The function does not allow to overwrite an already registered protocol. The unregister function simply replaces the mux slot with the default index pointer to IPPROTO_RAW as it was previously.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_input.c63
-rw-r--r--sys/netinet/ip_var.h2
2 files changed, 64 insertions, 1 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 37fbfd6..b950504 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -261,7 +261,7 @@ ip_init()
if (pr->pr_domain->dom_family == PF_INET &&
pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW) {
/* Be careful to only index valid IP protocols. */
- if (pr->pr_protocol && pr->pr_protocol < IPPROTO_MAX)
+ if (pr->pr_protocol <= IPPROTO_MAX)
ip_protox[pr->pr_protocol] = pr - inetsw;
}
@@ -1145,6 +1145,67 @@ ip_drain()
}
/*
+ * The protocol to be inserted into ip_protox[] must be already registered
+ * in inetsw[], either statically or through pf_proto_register().
+ */
+int
+ipproto_register(u_char ipproto)
+{
+ struct protosw *pr;
+
+ /* Sanity checks. */
+ if (ipproto == 0)
+ return (EPROTONOSUPPORT);
+
+ /*
+ * The protocol slot must not be occupied by another protocol
+ * already. An index pointing to IPPROTO_RAW is unused.
+ */
+ pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
+ if (pr == NULL)
+ return (EPFNOSUPPORT);
+ if (ip_protox[ipproto] != pr - inetsw) /* IPPROTO_RAW */
+ return (EEXIST);
+
+ /* Find the protocol position in inetsw[] and set the index. */
+ for (pr = inetdomain.dom_protosw;
+ 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);
+ }
+ }
+ return (EPROTONOSUPPORT);
+}
+
+int
+ipproto_unregister(u_char ipproto)
+{
+ struct protosw *pr;
+
+ /* Sanity checks. */
+ if (ipproto == 0)
+ return (EPROTONOSUPPORT);
+
+ /* Check if the protocol was indeed registered. */
+ pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
+ if (pr == NULL)
+ return (EPFNOSUPPORT);
+ if (ip_protox[ipproto] == pr - inetsw) /* IPPROTO_RAW */
+ return (ENOENT);
+
+ /* Reset the protocol slot to IPPROTO_RAW. */
+ ip_protox[ipproto] = pr - inetsw;
+ return (0);
+}
+
+
+/*
* Do option processing on a datagram,
* possibly discarding it if bad options are encountered,
* or forwarding it if source-routed.
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 2fa80d3..b4c99d2 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -168,6 +168,8 @@ extern int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
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);
struct mbuf *
ip_reass(struct mbuf *);
struct in_ifaddr *
OpenPOWER on IntegriCloud