summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorzec <zec@FreeBSD.org>2009-04-30 13:36:26 +0000
committerzec <zec@FreeBSD.org>2009-04-30 13:36:26 +0000
commit39b6dc8ba2de1c81754454858aae4fc4b706bdbf (patch)
tree47044959fbe0bb326af1b89e4cd6b6798fc96fa1 /sys/netinet
parente030268f0da956f47899e7e6ad7f3fd4bf34c434 (diff)
downloadFreeBSD-src-39b6dc8ba2de1c81754454858aae4fc4b706bdbf.zip
FreeBSD-src-39b6dc8ba2de1c81754454858aae4fc4b706bdbf.tar.gz
Permit buiding kernels with options VIMAGE, restricted to only a single
active network stack instance. Turning on options VIMAGE at compile time yields the following changes relative to default kernel build: 1) V_ accessor macros for virtualized variables resolve to structure fields via base pointers, instead of being resolved as fields in global structs or plain global variables. As an example, V_ifnet becomes: options VIMAGE: ((struct vnet_net *) vnet_net)->_ifnet default build: vnet_net_0._ifnet options VIMAGE_GLOBALS: ifnet 2) INIT_VNET_* macros will declare and set up base pointers to be used by V_ accessor macros, instead of resolving to whitespace: INIT_VNET_NET(ifp->if_vnet); becomes struct vnet_net *vnet_net = (ifp->if_vnet)->mod_data[VNET_MOD_NET]; 3) Memory for vnet modules registered via vnet_mod_register() is now allocated at run time in sys/kern/kern_vimage.c, instead of per vnet module structs being declared as globals. If required, vnet modules can now request the framework to provide them with allocated bzeroed memory by filling in the vmi_size field in their vmi_modinfo structures. 4) structs socket, ifnet, inpcbinfo, tcpcb and syncache_head are extended to hold a pointer to the parent vnet. options VIMAGE builds will fill in those fields as required. 5) curvnet is introduced as a new global variable in options VIMAGE builds, always pointing to the default and only struct vnet. 6) struct sysctl_oid has been extended with additional two fields to store major and minor virtualization module identifiers, oid_v_subs and oid_v_mod. SYSCTL_V_* family of macros will fill in those fields accordingly, and store the offset in the appropriate vnet container struct in oid_arg1. In sysctl handlers dealing with virtualized sysctls, the SYSCTL_RESOLVE_V_ARG1() macro will compute the address of the target variable and make it available in arg1 variable for further processing. Unused fields in structs vnet_inet, vnet_inet6 and vnet_ipfw have been deleted. Reviewed by: bz, rwatson Approved by: julian (mentor)
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/in_pcb.c4
-rw-r--r--sys/netinet/in_pcb.h10
-rw-r--r--sys/netinet/ip_divert.c3
-rw-r--r--sys/netinet/ip_fw.h2
-rw-r--r--sys/netinet/ip_fw_pfil.c2
-rw-r--r--sys/netinet/ip_input.c1
-rw-r--r--sys/netinet/raw_ip.c3
-rw-r--r--sys/netinet/tcp_subr.c6
-rw-r--r--sys/netinet/tcp_syncache.c3
-rw-r--r--sys/netinet/tcp_syncache.h1
-rw-r--r--sys/netinet/tcp_var.h8
-rw-r--r--sys/netinet/udp_usrreq.c3
-rw-r--r--sys/netinet/vinet.h2
13 files changed, 39 insertions, 9 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 9ff531a..dbc5ca8 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -126,7 +126,9 @@ sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS)
INIT_VNET_INET(curvnet);
int error;
- error = sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
+ SYSCTL_RESOLVE_V_ARG1();
+
+ error = sysctl_handle_int(oidp, arg1, arg2, req);
if (error == 0) {
RANGECHK(V_ipport_lowfirstauto, 1, IPPORT_RESERVED - 1);
RANGECHK(V_ipport_lowlastauto, 1, IPPORT_RESERVED - 1);
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 82b4126..c86f1ab 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -224,6 +224,8 @@ struct inpcb {
#define in6p_icmp6filt inp_depend6.inp6_icmp6filt
#define in6p_cksum inp_depend6.inp6_cksum
+#define inp_vnet inp_pcbinfo->ipi_vnet
+
/*
* The range of the generation count, as used in this implementation, is 9e19.
* We would have to create 300 billion connections per second for this number
@@ -301,8 +303,12 @@ struct inpcbinfo {
struct rwlock ipi_lock;
/*
- * vimage 1
- * general use 1
+ * Pointer to network stack instance
+ */
+ struct vnet *ipi_vnet;
+
+ /*
+ * general use 2
*/
void *ipi_pspare[2];
};
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index f88a8fd..3bd3049 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -162,6 +162,9 @@ div_init(void)
INP_INFO_LOCK_INIT(&V_divcbinfo, "div");
LIST_INIT(&V_divcb);
V_divcbinfo.ipi_listhead = &V_divcb;
+#ifdef VIMAGE
+ V_divcbinfo.ipi_vnet = curvnet;
+#endif
/*
* XXX We don't use the hash list for divert IP, but it's easier
* to allocate a one entry hash list than it is to check all
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index fa37a73..cfc3089 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -695,7 +695,6 @@ struct vnet_ipfw {
int _fw_deny_unknown_exthdrs;
int _fw_verbose;
int _verbose_limit;
- int _fw_debug; /* actually unused */
int _autoinc_step;
ipfw_dyn_rule **_ipfw_dyn_v;
uma_zone_t _ipfw_dyn_rule_zone;
@@ -740,7 +739,6 @@ extern struct vnet_ipfw vnet_ipfw_0;
#define V_fw_deny_unknown_exthdrs VNET_IPFW(fw_deny_unknown_exthdrs)
#define V_fw_verbose VNET_IPFW(fw_verbose)
#define V_verbose_limit VNET_IPFW(verbose_limit)
-#define V_fw_debug VNET_IPFW(fw_debug)
#define V_autoinc_step VNET_IPFW(autoinc_step)
#define V_ipfw_dyn_v VNET_IPFW(ipfw_dyn_v)
#define V_ipfw_dyn_rule_zone VNET_IPFW(ipfw_dyn_rule_zone)
diff --git a/sys/netinet/ip_fw_pfil.c b/sys/netinet/ip_fw_pfil.c
index c2f10b1..3064cd9 100644
--- a/sys/netinet/ip_fw_pfil.c
+++ b/sys/netinet/ip_fw_pfil.c
@@ -95,6 +95,7 @@ int
ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
+ INIT_VNET_INET(curvnet);
struct ip_fw_args args;
struct ng_ipfw_tag *ng_tag;
struct m_tag *dn_tag;
@@ -224,6 +225,7 @@ int
ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
+ INIT_VNET_INET(curvnet);
struct ip_fw_args args;
struct ng_ipfw_tag *ng_tag;
struct m_tag *dn_tag;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index a294d0a..7ee5a13 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -237,6 +237,7 @@ static void vnet_inet_register(void);
static const vnet_modinfo_t vnet_inet_modinfo = {
.vmi_id = VNET_MOD_INET,
.vmi_name = "inet",
+ .vmi_size = sizeof(struct vnet_inet)
};
static void vnet_inet_register()
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 0775168..695a9cb 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -187,6 +187,9 @@ rip_init(void)
INP_INFO_LOCK_INIT(&V_ripcbinfo, "rip");
LIST_INIT(&V_ripcb);
+#ifdef VIMAGE
+ V_ripcbinfo.ipi_vnet = curvnet;
+#endif
V_ripcbinfo.ipi_listhead = &V_ripcb;
V_ripcbinfo.ipi_hashbase =
hashinit(INP_PCBHASH_RAW_SIZE, M_PCB, &V_ripcbinfo.ipi_hashmask);
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 9e92aab..c1dc4b3 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -359,6 +359,9 @@ tcp_init(void)
INP_INFO_LOCK_INIT(&V_tcbinfo, "tcp");
LIST_INIT(&V_tcb);
+#ifdef VIMAGE
+ V_tcbinfo.ipi_vnet = curvnet;
+#endif
V_tcbinfo.ipi_listhead = &V_tcb;
hashsize = TCBHASHSIZE;
TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize);
@@ -703,6 +706,9 @@ tcp_newtcpcb(struct inpcb *inp)
if (tm == NULL)
return (NULL);
tp = &tm->tcb;
+#ifdef VIMAGE
+ tp->t_vnet = inp->inp_vnet;
+#endif
tp->t_timers = &tm->tt;
/* LIST_INIT(&tp->t_segq); */ /* XXX covered by M_ZERO */
tp->t_maxseg = tp->t_maxopd =
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 18f3fb4..8e80842 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -259,6 +259,9 @@ syncache_init(void)
/* Initialize the hash buckets. */
for (i = 0; i < V_tcp_syncache.hashsize; i++) {
+#ifdef VIMAGE
+ V_tcp_syncache.hashbase[i].sch_vnet = curvnet;
+#endif
TAILQ_INIT(&V_tcp_syncache.hashbase[i].sch_bucket);
mtx_init(&V_tcp_syncache.hashbase[i].sch_mtx, "tcp_sc_head",
NULL, MTX_DEF);
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index c367d33..e4e3fac 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -96,6 +96,7 @@ struct syncache {
#define SYNCOOKIE_LIFETIME 16 /* seconds */
struct syncache_head {
+ struct vnet *sch_vnet;
struct mtx sch_mtx;
TAILQ_HEAD(sch_head, syncache) sch_bucket;
struct callout sch_timer;
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 268db7c..5dc840e 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -35,6 +35,8 @@
#include <netinet/tcp.h>
+struct vnet;
+
/*
* Kernel variables for tcp.
*/
@@ -106,6 +108,8 @@ struct tcpcb {
int t_state; /* state of this connection */
u_int t_flags;
+ struct vnet *t_vnet; /* back pointer to parent vnet */
+
tcp_seq snd_una; /* send unacknowledged */
tcp_seq snd_max; /* highest sequence number sent;
* used to recognize retransmits
@@ -186,8 +190,8 @@ struct tcpcb {
int t_rttlow; /* smallest observerved RTT */
u_int32_t rfbuf_ts; /* recv buffer autoscaling timestamp */
int rfbuf_cnt; /* recv buffer autoscaling byte count */
- void *t_pspare[3]; /* toe usrreqs / toepcb * / congestion algo / vimage / 1 general use */
- struct toe_usrreqs *t_tu; /* offload operations vector */
+ void *t_pspare[3]; /* toe usrreqs / toepcb * / congestion algo / 1 general use */
+ struct toe_usrreqs *t_tu; /* offload operations vector */
void *t_toe; /* TOE pcb pointer */
int t_bytes_acked; /* # bytes acked during current RTT */
};
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index f2359eb..9aa83dd 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -179,6 +179,9 @@ udp_init(void)
INP_INFO_LOCK_INIT(&V_udbinfo, "udp");
LIST_INIT(&V_udb);
+#ifdef VIMAGE
+ V_udbinfo.ipi_vnet = curvnet;
+#endif
V_udbinfo.ipi_listhead = &V_udb;
V_udbinfo.ipi_hashbase = hashinit(UDBHASHSIZE, M_PCB,
&V_udbinfo.ipi_hashmask);
diff --git a/sys/netinet/vinet.h b/sys/netinet/vinet.h
index 20a36c5..0057eff 100644
--- a/sys/netinet/vinet.h
+++ b/sys/netinet/vinet.h
@@ -54,7 +54,6 @@ struct vnet_inet {
struct in_ifaddrhashhead *_in_ifaddrhashtbl;
struct in_ifaddrhead _in_ifaddrhead;
u_long _in_ifaddrhmask;
- struct in_multihead _in_multihead; /* XXX unused */
int _arpt_keep;
int _arp_maxtries;
@@ -269,7 +268,6 @@ extern struct vnet_inet vnet_inet_0;
#define V_in_ifaddrhashtbl VNET_INET(in_ifaddrhashtbl)
#define V_in_ifaddrhead VNET_INET(in_ifaddrhead)
#define V_in_ifaddrhmask VNET_INET(in_ifaddrhmask)
-#define V_in_multihead VNET_INET(in_multihead)
#define V_ip_checkinterface VNET_INET(ip_checkinterface)
#define V_ip_defttl VNET_INET(ip_defttl)
#define V_ip_do_randomid VNET_INET(ip_do_randomid)
OpenPOWER on IntegriCloud