changeset 4961:230b3e3e0890

PSARC/2007/250 CGTP for IP Instances 6572777 Need CGTP hooks version 3 to allow per-IP instance hooks
author nordmark
date Wed, 29 Aug 2007 17:12:04 -0700
parents a4746a82a247
children 44219572abba
files usr/src/uts/common/inet/ip.h usr/src/uts/common/inet/ip/ip.c usr/src/uts/common/inet/ip/ip6.c usr/src/uts/common/inet/ip/ip6_if.c usr/src/uts/common/inet/ip/ip_ftable.c usr/src/uts/common/inet/ip/ip_if.c usr/src/uts/common/inet/ip_stack.h usr/src/uts/intel/ip/ip.global-objs.debug64 usr/src/uts/intel/ip/ip.global-objs.obj64 usr/src/uts/sparc/ip/ip.global-objs.debug64 usr/src/uts/sparc/ip/ip.global-objs.obj64
diffstat 11 files changed, 153 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/inet/ip.h	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/common/inet/ip.h	Wed Aug 29 17:12:04 2007 -0700
@@ -3279,39 +3279,42 @@
 /* Hooks for CGTP (multirt routes) filtering module */
 #define	CGTP_FILTER_REV_1	1
 #define	CGTP_FILTER_REV_2	2
-#define	CGTP_FILTER_REV		CGTP_FILTER_REV_2
-
-/* cfo_filter, cfo_filter_fp, cfo_filter_v6 hooks return values */
+#define	CGTP_FILTER_REV_3	3
+#define	CGTP_FILTER_REV		CGTP_FILTER_REV_3
+
+/* cfo_filter and cfo_filter_v6 hooks return values */
 #define	CGTP_IP_PKT_NOT_CGTP	0
 #define	CGTP_IP_PKT_PREMIUM	1
 #define	CGTP_IP_PKT_DUPLICATE	2
 
+/* Version 3 of the filter interface */
 typedef struct cgtp_filter_ops {
-	int	cfo_filter_rev;
-	int	(*cfo_change_state)(int);
-	int	(*cfo_add_dest_v4)(ipaddr_t, ipaddr_t, ipaddr_t, ipaddr_t);
-	int	(*cfo_del_dest_v4)(ipaddr_t, ipaddr_t);
-	int	(*cfo_add_dest_v6)(in6_addr_t *, in6_addr_t *, in6_addr_t *,
-		    in6_addr_t *);
-	int	(*cfo_del_dest_v6)(in6_addr_t *, in6_addr_t *);
-	int	(*cfo_filter)(queue_t *, mblk_t *);
-	int	(*cfo_filter_fp)(queue_t *, mblk_t *);
-	int	(*cfo_filter_v6)(queue_t *, ip6_t *, ip6_frag_t *);
+	int	cfo_filter_rev;			/* CGTP_FILTER_REV_3 */
+	int	(*cfo_change_state)(netstackid_t, int);
+	int	(*cfo_add_dest_v4)(netstackid_t, ipaddr_t, ipaddr_t,
+		    ipaddr_t, ipaddr_t);
+	int	(*cfo_del_dest_v4)(netstackid_t, ipaddr_t, ipaddr_t);
+	int	(*cfo_add_dest_v6)(netstackid_t, in6_addr_t *, in6_addr_t *,
+		    in6_addr_t *, in6_addr_t *);
+	int	(*cfo_del_dest_v6)(netstackid_t, in6_addr_t *, in6_addr_t *);
+	int	(*cfo_filter)(netstackid_t, uint_t, mblk_t *);
+	int	(*cfo_filter_v6)(netstackid_t, uint_t, ip6_t *,
+		    ip6_frag_t *);
 } cgtp_filter_ops_t;
 
 #define	CGTP_MCAST_SUCCESS	1
 
 /*
- * The separate CGTP module needs these as globals. It uses the first
- * to unregister (since there is no ip_cgtp_filter_unregister() function)
- * and it uses the second one to verify that the filter has been
- * turned off (a ip_cgtp_filter_active() function would be good for that.)
+ * The separate CGTP module needs this global symbol so that it
+ * can check the version and determine whether to use the old or the new
+ * version of the filtering interface.
  */
-extern cgtp_filter_ops_t *ip_cgtp_filter_ops;
-extern boolean_t ip_cgtp_filter;
+extern int	ip_cgtp_filter_rev;
 
 extern int	ip_cgtp_filter_supported(void);
-extern int	ip_cgtp_filter_register(cgtp_filter_ops_t *);
+extern int	ip_cgtp_filter_register(netstackid_t, cgtp_filter_ops_t *);
+extern int	ip_cgtp_filter_unregister(netstackid_t);
+extern int	ip_cgtp_filter_is_registered(netstackid_t);
 
 /* Flags for ire_multirt_lookup() */
 
--- a/usr/src/uts/common/inet/ip/ip.c	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/common/inet/ip/ip.c	Wed Aug 29 17:12:04 2007 -0700
@@ -793,9 +793,7 @@
 /*
  * Multirouting/CGTP stuff
  */
-cgtp_filter_ops_t	*ip_cgtp_filter_ops;	/* CGTP hooks */
 int	ip_cgtp_filter_rev = CGTP_FILTER_REV;	/* CGTP hooks version */
-boolean_t	ip_cgtp_filter;		/* Enable/disable CGTP hooks */
 
 /*
  * XXX following really should only be in a header. Would need more
@@ -6014,7 +6012,7 @@
 	ASSERT(strcmp(ipst->ips_ndp_arr[IPNDP_CGTP_FILTER_OFFSET].ip_ndp_name,
 	    "ip_cgtp_filter") == 0);
 	ipst->ips_ndp_arr[IPNDP_CGTP_FILTER_OFFSET].ip_ndp_data =
-	    (caddr_t)&ip_cgtp_filter;
+	    (caddr_t)&ipst->ips_ip_cgtp_filter;
 	ASSERT(strcmp(ipst->ips_ndp_arr[IPNDP_IPMP_HOOK_OFFSET].ip_ndp_name,
 	    "ipmp_hook_emulation") == 0);
 	ipst->ips_ndp_arr[IPNDP_IPMP_HOOK_OFFSET].ip_ndp_data =
@@ -14856,7 +14854,7 @@
 		 * 	o not a multicast packet
 		 */
 		if (!is_system_labeled() &&
-		    !ip_cgtp_filter && ipp_action_count == 0 &&
+		    !ipst->ips_ip_cgtp_filter && ipp_action_count == 0 &&
 		    opt_len == 0 && ipha->ipha_protocol != IPPROTO_RSVP &&
 		    !ll_multicast && !CLASSD(dst)) {
 			if (ire == NULL)
@@ -14898,15 +14896,16 @@
 		 * the incoming packet. Packets identified as duplicates
 		 * must be discarded. Filtering is active only if the
 		 * the ip_cgtp_filter ndd variable is non-zero.
-		 *
-		 * Only applies to the shared stack since the filter_ops
-		 * do not carry an ip_stack_t or zoneid.
 		 */
 		cgtp_flt_pkt = CGTP_IP_PKT_NOT_CGTP;
-		if (ip_cgtp_filter && (ip_cgtp_filter_ops != NULL) &&
-		    ipst->ips_netstack->netstack_stackid == GLOBAL_NETSTACKID) {
+		if (ipst->ips_ip_cgtp_filter &&
+		    ipst->ips_ip_cgtp_filter_ops != NULL) {
+			netstackid_t stackid;
+
+			stackid = ipst->ips_netstack->netstack_stackid;
 			cgtp_flt_pkt =
-			    ip_cgtp_filter_ops->cfo_filter(q, mp);
+			    ipst->ips_ip_cgtp_filter_ops->cfo_filter(stackid,
+			    ill->ill_phyint->phyint_ifindex, mp);
 			if (cgtp_flt_pkt == CGTP_IP_PKT_DUPLICATE) {
 				freemsg(first_mp);
 				continue;
@@ -28736,14 +28735,6 @@
 ip_cgtp_filter_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *ioc_cr)
 {
 	boolean_t	*ip_cgtp_filter_value = (boolean_t *)cp;
-	ip_stack_t	*ipst = CONNQ_TO_IPST(q);
-
-	/*
-	 * Only applies to the shared stack since the filter_ops
-	 * do not carry an ip_stack_t or zoneid.
-	 */
-	if (ipst->ips_netstack->netstack_stackid != GLOBAL_NETSTACKID)
-		return (ENOTSUP);
 
 	(void) mi_mpprintf(mp, "%d", (int)*ip_cgtp_filter_value);
 	return (0);
@@ -28765,50 +28756,32 @@
 	boolean_t	*ip_cgtp_filter_value = (boolean_t *)cp;
 	ip_stack_t	*ipst = CONNQ_TO_IPST(q);
 
-	if (secpolicy_net_config(ioc_cr, B_FALSE) != 0)
+	if (secpolicy_ip_config(ioc_cr, B_FALSE) != 0)
 		return (EPERM);
 
-	/*
-	 * Only applies to the shared stack since the filter_ops
-	 * do not carry an ip_stack_t or zoneid.
-	 */
-	if (ipst->ips_netstack->netstack_stackid != GLOBAL_NETSTACKID)
-		return (ENOTSUP);
-
 	if (ddi_strtol(value, NULL, 10, &new_value) != 0 ||
 	    new_value < 0 || new_value > 1) {
 		return (EINVAL);
 	}
 
-	/*
-	 * Do not enable CGTP filtering - thus preventing the hooks
-	 * from being invoked - if the version number of the
-	 * filtering module hooks does not match.
-	 */
-	if ((ip_cgtp_filter_ops != NULL) &&
-	    (ip_cgtp_filter_ops->cfo_filter_rev != CGTP_FILTER_REV)) {
-		cmn_err(CE_WARN, "IP: CGTP filtering version mismatch "
-		    "(module hooks version %d, expecting %d)\n",
-		    ip_cgtp_filter_ops->cfo_filter_rev,
-		    CGTP_FILTER_REV);
-		return (ENOTSUP);
-	}
-
 	if ((!*ip_cgtp_filter_value) && new_value) {
 		cmn_err(CE_NOTE, "IP: enabling CGTP filtering%s",
-		    ip_cgtp_filter_ops == NULL ?
+		    ipst->ips_ip_cgtp_filter_ops == NULL ?
 		    " (module not loaded)" : "");
 	}
 	if (*ip_cgtp_filter_value && (!new_value)) {
 		cmn_err(CE_NOTE, "IP: disabling CGTP filtering%s",
-		    ip_cgtp_filter_ops == NULL ?
+		    ipst->ips_ip_cgtp_filter_ops == NULL ?
 		    " (module not loaded)" : "");
 	}
 
-	if (ip_cgtp_filter_ops != NULL) {
+	if (ipst->ips_ip_cgtp_filter_ops != NULL) {
 		int	res;
-
-		res = ip_cgtp_filter_ops->cfo_change_state(new_value);
+		netstackid_t stackid;
+
+		stackid = ipst->ips_netstack->netstack_stackid;
+		res = ipst->ips_ip_cgtp_filter_ops->cfo_change_state(stackid,
+		    new_value);
 		if (res)
 			return (res);
 	}
@@ -28825,44 +28798,97 @@
 int
 ip_cgtp_filter_supported(void)
 {
-	ip_stack_t *ipst;
-	int ret;
-
-	ipst = netstack_find_by_stackid(GLOBAL_NETSTACKID)->netstack_ip;
-	if (ipst == NULL)
-		return (-1);
-	ret = ip_cgtp_filter_rev;
-	netstack_rele(ipst->ips_netstack);
-	return (ret);
-}
-
-
-/*
- * CGTP hooks can be registered by directly touching ip_cgtp_filter_ops
- * or by invoking this function. In the first case, the version number
- * of the registered structure is checked at hooks activation time
- * in ip_cgtp_filter_set().
- *
- * Only applies to the shared stack since the filter_ops
- * do not carry an ip_stack_t or zoneid.
+	return (ip_cgtp_filter_rev);
+}
+
+
+/*
+ * CGTP hooks can be registered by invoking this function.
+ * Checks that the version number matches.
  */
 int
-ip_cgtp_filter_register(cgtp_filter_ops_t *ops)
-{
+ip_cgtp_filter_register(netstackid_t stackid, cgtp_filter_ops_t *ops)
+{
+	netstack_t *ns;
 	ip_stack_t *ipst;
 
 	if (ops->cfo_filter_rev != CGTP_FILTER_REV)
 		return (ENOTSUP);
 
-	ipst = netstack_find_by_stackid(GLOBAL_NETSTACKID)->netstack_ip;
-	if (ipst == NULL)
+	ns = netstack_find_by_stackid(stackid);
+	if (ns == NULL)
+		return (EINVAL);
+	ipst = ns->netstack_ip;
+	ASSERT(ipst != NULL);
+
+	if (ipst->ips_ip_cgtp_filter_ops != NULL) {
+		netstack_rele(ns);
+		return (EALREADY);
+	}
+
+	ipst->ips_ip_cgtp_filter_ops = ops;
+	netstack_rele(ns);
+	return (0);
+}
+
+/*
+ * CGTP hooks can be unregistered by invoking this function.
+ * Returns ENXIO if there was no registration.
+ * Returns EBUSY if the ndd variable has not been turned off.
+ */
+int
+ip_cgtp_filter_unregister(netstackid_t stackid)
+{
+	netstack_t *ns;
+	ip_stack_t *ipst;
+
+	ns = netstack_find_by_stackid(stackid);
+	if (ns == NULL)
 		return (EINVAL);
-
-	ip_cgtp_filter_ops = ops;
-	netstack_rele(ipst->ips_netstack);
+	ipst = ns->netstack_ip;
+	ASSERT(ipst != NULL);
+
+	if (ipst->ips_ip_cgtp_filter) {
+		netstack_rele(ns);
+		return (EBUSY);
+	}
+
+	if (ipst->ips_ip_cgtp_filter_ops == NULL) {
+		netstack_rele(ns);
+		return (ENXIO);
+	}
+	ipst->ips_ip_cgtp_filter_ops = NULL;
+	netstack_rele(ns);
 	return (0);
 }
 
+/*
+ * Check whether there is a CGTP filter registration.
+ * Returns non-zero if there is a registration, otherwise returns zero.
+ * Note: returns zero if bad stackid.
+ */
+int
+ip_cgtp_filter_is_registered(netstackid_t stackid)
+{
+	netstack_t *ns;
+	ip_stack_t *ipst;
+	int ret;
+
+	ns = netstack_find_by_stackid(stackid);
+	if (ns == NULL)
+		return (0);
+	ipst = ns->netstack_ip;
+	ASSERT(ipst != NULL);
+
+	if (ipst->ips_ip_cgtp_filter_ops != NULL)
+		ret = 1;
+	else
+		ret = 0;
+
+	netstack_rele(ns);
+	return (ret);
+}
+
 static squeue_func_t
 ip_squeue_switch(int val)
 {
--- a/usr/src/uts/common/inet/ip/ip6.c	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/common/inet/ip/ip6.c	Wed Aug 29 17:12:04 2007 -0700
@@ -8167,16 +8167,18 @@
 			 * duplicates must be discarded. Filtering is active
 			 * only if the the ip_cgtp_filter ndd variable is
 			 * non-zero.
-			 *
-			 * Only applies to the shared stack since the
-			 * filter_ops do not carry an ip_stack_t or zoneid.
-			 */
-			if (ip_cgtp_filter && (ip_cgtp_filter_ops != NULL) &&
-			    ipst->ips_netstack->netstack_stackid ==
-			    GLOBAL_NETSTACKID) {
-				int cgtp_flt_pkt =
-				    ip_cgtp_filter_ops->cfo_filter_v6(
-				    inill->ill_rq, ip6h, fraghdr);
+			 */
+			if (ipst->ips_ip_cgtp_filter &&
+			    ipst->ips_ip_cgtp_filter_ops != NULL) {
+				int cgtp_flt_pkt;
+				netstackid_t stackid;
+
+				stackid = ipst->ips_netstack->netstack_stackid;
+
+				cgtp_flt_pkt =
+				    ipst->ips_ip_cgtp_filter_ops->cfo_filter_v6(
+				    stackid, inill->ill_phyint->phyint_ifindex,
+				    ip6h, fraghdr);
 				if (cgtp_flt_pkt == CGTP_IP_PKT_DUPLICATE) {
 					freemsg(mp);
 					return;
--- a/usr/src/uts/common/inet/ip/ip6_if.c	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/common/inet/ip/ip6_if.c	Wed Aug 29 17:12:04 2007 -0700
@@ -821,10 +821,12 @@
 		 * when the dst address is a multicast, because an
 		 * IP source address cannot be a multicast.
 		 */
-		if ((ip_cgtp_filter_ops != NULL) &&
-		    ipst->ips_netstack->netstack_stackid == GLOBAL_NETSTACKID &&
+		if (ipst->ips_ip_cgtp_filter_ops != NULL &&
 		    !IN6_IS_ADDR_MULTICAST(&(ire->ire_addr_v6))) {
-			int res = ip_cgtp_filter_ops->cfo_add_dest_v6(
+			int res;
+
+			res = ipst->ips_ip_cgtp_filter_ops->cfo_add_dest_v6(
+			    ipst->ips_netstack->netstack_stackid,
 			    &ire->ire_addr_v6,
 			    &ire->ire_gateway_addr_v6,
 			    &ire->ire_src_addr_v6,
@@ -1022,9 +1024,9 @@
 		 * Packets coming from that address will no longer be
 		 * filtered to remove duplicates.
 		 */
-		if (ip_cgtp_filter_ops != NULL &&
-		    ipst->ips_netstack->netstack_stackid == GLOBAL_NETSTACKID) {
-			err = ip_cgtp_filter_ops->cfo_del_dest_v6(
+		if (ipst->ips_ip_cgtp_filter_ops != NULL) {
+			err = ipst->ips_ip_cgtp_filter_ops->cfo_del_dest_v6(
+			    ipst->ips_netstack->netstack_stackid,
 			    &ire->ire_addr_v6, &ire->ire_gateway_addr_v6);
 		}
 	}
--- a/usr/src/uts/common/inet/ip/ip_ftable.c	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/common/inet/ip/ip_ftable.c	Wed Aug 29 17:12:04 2007 -0700
@@ -831,7 +831,7 @@
 	 * This essentially prevents insertion of incomplete RTF_MULTIRT
 	 * ires in cachetable.
 	 */
-	if (ip_cgtp_filter &&
+	if (ipst->ips_ip_cgtp_filter &&
 	    ((ire->ire_flags & RTF_MULTIRT) ||
 	    ((sire != NULL) && (sire->ire_flags & RTF_MULTIRT)))) {
 		ip3dbg(("ire_forward: packet is to be multirouted- "
@@ -1363,7 +1363,7 @@
 	}
 
 	/* IP Filter and CGTP dont mix. So bail out if CGTP is on */
-	if (ip_cgtp_filter &&
+	if (ipst->ips_ip_cgtp_filter &&
 	    ((ire->ire_flags & RTF_MULTIRT) ||
 	    ((sire != NULL) && (sire->ire_flags & RTF_MULTIRT)))) {
 		ip1dbg(("ipfil_sendpkt: IPFilter does not work with CGTP\n"));
--- a/usr/src/uts/common/inet/ip/ip_if.c	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/common/inet/ip/ip_if.c	Wed Aug 29 17:12:04 2007 -0700
@@ -7278,9 +7278,10 @@
 			ire_refrele(ire_dst);
 			goto save_ire;
 		}
-		if ((ip_cgtp_filter_ops != NULL) && !CLASSD(ire->ire_addr) &&
-		    ipst->ips_netstack->netstack_stackid == GLOBAL_NETSTACKID) {
-			int res = ip_cgtp_filter_ops->cfo_add_dest_v4(
+		if (ipst->ips_ip_cgtp_filter_ops != NULL &&
+		    !CLASSD(ire->ire_addr)) {
+			int res = ipst->ips_ip_cgtp_filter_ops->cfo_add_dest_v4(
+			    ipst->ips_netstack->netstack_stackid,
 			    ire->ire_addr,
 			    ire->ire_gateway_addr,
 			    ire->ire_src_addr,
@@ -7465,9 +7466,9 @@
 		 * Packets coming from that address will no longer be
 		 * filtered to remove duplicates.
 		 */
-		if (ip_cgtp_filter_ops != NULL &&
-		    ipst->ips_netstack->netstack_stackid == GLOBAL_NETSTACKID) {
-			err = ip_cgtp_filter_ops->cfo_del_dest_v4(
+		if (ipst->ips_ip_cgtp_filter_ops != NULL) {
+			err = ipst->ips_ip_cgtp_filter_ops->cfo_del_dest_v4(
+			    ipst->ips_netstack->netstack_stackid,
 			    ire->ire_addr, ire->ire_gateway_addr);
 		}
 		ip_cgtp_bcast_delete(ire, ipst);
--- a/usr/src/uts/common/inet/ip_stack.h	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/common/inet/ip_stack.h	Wed Aug 29 17:12:04 2007 -0700
@@ -308,6 +308,9 @@
 	/* Time since last warning issued. */
 	hrtime_t	ips_multirt_bad_mtu_last_time;
 
+	struct cgtp_filter_ops *ips_ip_cgtp_filter_ops;	/* CGTP hooks */
+	boolean_t	ips_ip_cgtp_filter;	/* Enable/disable CGTP hooks */
+
 	kmutex_t	ips_ip_trash_timer_lock;
 	timeout_id_t	ips_ip_ire_expire_id;	/* IRE expiration timer. */
 	struct ipsq_s	*ips_ipsq_g_head;
--- a/usr/src/uts/intel/ip/ip.global-objs.debug64	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/intel/ip/ip.global-objs.debug64	Wed Aug 29 17:12:04 2007 -0700
@@ -88,8 +88,6 @@
 ip_aron_template
 ip_aru_template
 ip_cache_table_size
-ip_cgtp_filter
-ip_cgtp_filter_ops
 ip_cgtp_filter_rev
 ip_debug
 ip_g_all_ones
--- a/usr/src/uts/intel/ip/ip.global-objs.obj64	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/intel/ip/ip.global-objs.obj64	Wed Aug 29 17:12:04 2007 -0700
@@ -88,8 +88,6 @@
 ip_aron_template
 ip_aru_template
 ip_cache_table_size
-ip_cgtp_filter
-ip_cgtp_filter_ops
 ip_cgtp_filter_rev
 ip_debug
 ip_g_all_ones
--- a/usr/src/uts/sparc/ip/ip.global-objs.debug64	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/sparc/ip/ip.global-objs.debug64	Wed Aug 29 17:12:04 2007 -0700
@@ -88,8 +88,6 @@
 ip_aron_template
 ip_aru_template
 ip_cache_table_size
-ip_cgtp_filter
-ip_cgtp_filter_ops
 ip_cgtp_filter_rev
 ip_debug
 ip_g_all_ones
--- a/usr/src/uts/sparc/ip/ip.global-objs.obj64	Wed Aug 29 16:06:42 2007 -0700
+++ b/usr/src/uts/sparc/ip/ip.global-objs.obj64	Wed Aug 29 17:12:04 2007 -0700
@@ -88,8 +88,6 @@
 ip_aron_template
 ip_aru_template
 ip_cache_table_size
-ip_cgtp_filter
-ip_cgtp_filter_ops
 ip_cgtp_filter_rev
 ip_debug
 ip_g_all_ones