Mercurial > illumos > illumos-gate
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