Print this page
Reduce lint
OS-5007 support SO_ATTACH_FILTER on ICMP sockets
Reviewed by: Cody Mello <melloc@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4018 lxbrand support TCP SO_REUSEPORT
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Cody Mello <cody.mello@joyent.com>

*** 18,27 **** --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2016 Joyent, Inc. */ /* * IP PACKET CLASSIFIER *
*** 866,936 **** mutex_enter(&(connfp)->connf_lock); \ IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp); \ mutex_exit(&(connfp)->connf_lock); \ } ! #define IPCL_HASH_INSERT_BOUND(connfp, connp) { \ ! conn_t *pconnp = NULL, *nconnp; \ ! IPCL_HASH_REMOVE((connp)); \ ! mutex_enter(&(connfp)->connf_lock); \ ! nconnp = (connfp)->connf_head; \ ! while (nconnp != NULL && \ ! !_IPCL_V4_MATCH_ANY(nconnp->conn_laddr_v6)) { \ ! pconnp = nconnp; \ ! nconnp = nconnp->conn_next; \ ! } \ ! if (pconnp != NULL) { \ ! pconnp->conn_next = (connp); \ ! (connp)->conn_prev = pconnp; \ ! } else { \ ! (connfp)->connf_head = (connp); \ ! } \ ! if (nconnp != NULL) { \ ! (connp)->conn_next = nconnp; \ ! nconnp->conn_prev = (connp); \ ! } \ ! (connp)->conn_fanout = (connfp); \ ! (connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) | \ ! IPCL_BOUND; \ ! CONN_INC_REF(connp); \ ! mutex_exit(&(connfp)->connf_lock); \ ! } ! #define IPCL_HASH_INSERT_WILDCARD(connfp, connp) { \ ! conn_t **list, *prev, *next; \ ! boolean_t isv4mapped = \ ! IN6_IS_ADDR_V4MAPPED(&(connp)->conn_laddr_v6); \ ! IPCL_HASH_REMOVE((connp)); \ ! mutex_enter(&(connfp)->connf_lock); \ ! list = &(connfp)->connf_head; \ ! prev = NULL; \ ! while ((next = *list) != NULL) { \ ! if (isv4mapped && \ ! IN6_IS_ADDR_UNSPECIFIED(&next->conn_laddr_v6) && \ ! connp->conn_zoneid == next->conn_zoneid) { \ ! (connp)->conn_next = next; \ ! if (prev != NULL) \ ! prev = next->conn_prev; \ ! next->conn_prev = (connp); \ ! break; \ ! } \ ! list = &next->conn_next; \ ! prev = next; \ ! } \ ! (connp)->conn_prev = prev; \ ! *list = (connp); \ ! (connp)->conn_fanout = (connfp); \ ! (connp)->conn_flags = ((connp)->conn_flags & ~IPCL_REMOVED) | \ ! IPCL_BOUND; \ ! CONN_INC_REF((connp)); \ ! mutex_exit(&(connfp)->connf_lock); \ } void ipcl_hash_insert_wildcard(connf_t *connfp, conn_t *connp) { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } /* * Because the classifier is used to classify inbound packets, the destination * address is meant to be our local tunnel address (tunnel source), and the --- 867,960 ---- mutex_enter(&(connfp)->connf_lock); \ IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp); \ mutex_exit(&(connfp)->connf_lock); \ } ! /* ! * When inserting bound or wildcard entries into the hash, ordering rules are ! * used to facilitate timely and correct lookups. The order is as follows: ! * 1. Entries bound to a specific address ! * 2. Entries bound to INADDR_ANY ! * 3. Entries bound to ADDR_UNSPECIFIED ! * Entries in a category which share conn_lport (such as those using ! * SO_REUSEPORT) will be ordered such that the newest inserted is first. ! */ ! void ! ipcl_hash_insert_bound(connf_t *connfp, conn_t *connp) ! { ! conn_t *pconnp, *nconnp; ! ! IPCL_HASH_REMOVE(connp); ! mutex_enter(&connfp->connf_lock); ! nconnp = connfp->connf_head; ! pconnp = NULL; ! while (nconnp != NULL) { ! /* ! * Walk though entries associated with the fanout until one is ! * found which fulfills any of these conditions: ! * 1. Listen address of ADDR_ANY/ADDR_UNSPECIFIED ! * 2. Listen port the same as connp ! */ ! if (_IPCL_V4_MATCH_ANY(nconnp->conn_laddr_v6) || ! connp->conn_lport == nconnp->conn_lport) ! break; ! pconnp = nconnp; ! nconnp = nconnp->conn_next; ! } ! if (pconnp != NULL) { ! pconnp->conn_next = connp; ! connp->conn_prev = pconnp; ! } else { ! connfp->connf_head = connp; ! } ! if (nconnp != NULL) { ! connp->conn_next = nconnp; ! nconnp->conn_prev = connp; ! } ! connp->conn_fanout = connfp; ! connp->conn_flags = (connp->conn_flags & ~IPCL_REMOVED) | IPCL_BOUND; ! CONN_INC_REF(connp); ! mutex_exit(&connfp->connf_lock); } void ipcl_hash_insert_wildcard(connf_t *connfp, conn_t *connp) { ! conn_t *pconnp = NULL, *nconnp; ! boolean_t isv4mapped = IN6_IS_ADDR_V4MAPPED(&connp->conn_laddr_v6); ! ! IPCL_HASH_REMOVE(connp); ! mutex_enter(&connfp->connf_lock); ! nconnp = connfp->connf_head; ! pconnp = NULL; ! while (nconnp != NULL) { ! if (IN6_IS_ADDR_V4MAPPED_ANY(&nconnp->conn_laddr_v6) && ! isv4mapped && connp->conn_lport == nconnp->conn_lport) ! break; ! if (IN6_IS_ADDR_UNSPECIFIED(&nconnp->conn_laddr_v6) && ! (isv4mapped || ! connp->conn_lport == nconnp->conn_lport)) ! break; ! ! pconnp = nconnp; ! nconnp = nconnp->conn_next; ! } ! if (pconnp != NULL) { ! pconnp->conn_next = connp; ! connp->conn_prev = pconnp; ! } else { ! connfp->connf_head = connp; ! } ! if (nconnp != NULL) { ! connp->conn_next = nconnp; ! nconnp->conn_prev = connp; ! } ! connp->conn_fanout = connfp; ! connp->conn_flags = (connp->conn_flags & ~IPCL_REMOVED) | IPCL_BOUND; ! CONN_INC_REF(connp); ! mutex_exit(&connfp->connf_lock); } /* * Because the classifier is used to classify inbound packets, the destination * address is meant to be our local tunnel address (tunnel source), and the
*** 1032,1044 **** if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) || IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_faddr_v6)) { if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) || IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_laddr_v6)) { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } else { ! IPCL_HASH_INSERT_BOUND(connfp, connp); } } else { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } return (0); --- 1056,1068 ---- if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6) || IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_faddr_v6)) { if (IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6) || IN6_IS_ADDR_V4MAPPED_ANY(&connp->conn_laddr_v6)) { ! ipcl_hash_insert_wildcard(connfp, connp); } else { ! ipcl_hash_insert_bound(connfp, connp); } } else { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } return (0);
*** 1203,1215 **** } if (connp->conn_faddr_v4 != INADDR_ANY) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (connp->conn_laddr_v4 != INADDR_ANY) { ! IPCL_HASH_INSERT_BOUND(connfp, connp); } else { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } if (protocol == IPPROTO_RSVP) ill_set_inputfn_all(ipst); break; --- 1227,1239 ---- } if (connp->conn_faddr_v4 != INADDR_ANY) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (connp->conn_laddr_v4 != INADDR_ANY) { ! ipcl_hash_insert_bound(connfp, connp); } else { ! ipcl_hash_insert_wildcard(connfp, connp); } if (protocol == IPPROTO_RSVP) ill_set_inputfn_all(ipst); break;
*** 1217,1229 **** /* Insert it in the Bind Hash */ ASSERT(connp->conn_zoneid != ALL_ZONES); connfp = &ipst->ips_ipcl_bind_fanout[ IPCL_BIND_HASH(lport, ipst)]; if (connp->conn_laddr_v4 != INADDR_ANY) { ! IPCL_HASH_INSERT_BOUND(connfp, connp); } else { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } if (cl_inet_listen != NULL) { ASSERT(connp->conn_ipversion == IPV4_VERSION); connp->conn_flags |= IPCL_CL_LISTENER; (*cl_inet_listen)( --- 1241,1253 ---- /* Insert it in the Bind Hash */ ASSERT(connp->conn_zoneid != ALL_ZONES); connfp = &ipst->ips_ipcl_bind_fanout[ IPCL_BIND_HASH(lport, ipst)]; if (connp->conn_laddr_v4 != INADDR_ANY) { ! ipcl_hash_insert_bound(connfp, connp); } else { ! ipcl_hash_insert_wildcard(connfp, connp); } if (cl_inet_listen != NULL) { ASSERT(connp->conn_ipversion == IPV4_VERSION); connp->conn_flags |= IPCL_CL_LISTENER; (*cl_inet_listen)(
*** 1269,1293 **** } if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) { ! IPCL_HASH_INSERT_BOUND(connfp, connp); } else { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } break; case IPPROTO_TCP: /* Insert it in the Bind Hash */ ASSERT(connp->conn_zoneid != ALL_ZONES); connfp = &ipst->ips_ipcl_bind_fanout[ IPCL_BIND_HASH(lport, ipst)]; if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) { ! IPCL_HASH_INSERT_BOUND(connfp, connp); } else { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } if (cl_inet_listen != NULL) { sa_family_t addr_family; uint8_t *laddrp; --- 1293,1317 ---- } if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) { ! ipcl_hash_insert_bound(connfp, connp); } else { ! ipcl_hash_insert_wildcard(connfp, connp); } break; case IPPROTO_TCP: /* Insert it in the Bind Hash */ ASSERT(connp->conn_zoneid != ALL_ZONES); connfp = &ipst->ips_ipcl_bind_fanout[ IPCL_BIND_HASH(lport, ipst)]; if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) { ! ipcl_hash_insert_bound(connfp, connp); } else { ! ipcl_hash_insert_wildcard(connfp, connp); } if (cl_inet_listen != NULL) { sa_family_t addr_family; uint8_t *laddrp;
*** 1414,1426 **** } if (connp->conn_faddr_v4 != INADDR_ANY) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (connp->conn_laddr_v4 != INADDR_ANY) { ! IPCL_HASH_INSERT_BOUND(connfp, connp); } else { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } break; } return (ret); --- 1438,1450 ---- } if (connp->conn_faddr_v4 != INADDR_ANY) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (connp->conn_laddr_v4 != INADDR_ANY) { ! ipcl_hash_insert_bound(connfp, connp); } else { ! ipcl_hash_insert_wildcard(connfp, connp); } break; } return (ret);
*** 1502,1514 **** } if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) { ! IPCL_HASH_INSERT_BOUND(connfp, connp); } else { ! IPCL_HASH_INSERT_WILDCARD(connfp, connp); } break; } return (ret); --- 1526,1538 ---- } if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_faddr_v6)) { IPCL_HASH_INSERT_CONNECTED(connfp, connp); } else if (!IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) { ! ipcl_hash_insert_bound(connfp, connp); } else { ! ipcl_hash_insert_wildcard(connfp, connp); } break; } return (ret);
*** 2090,2099 **** --- 2114,2124 ---- cv_init(&connp->conn_cv, NULL, CV_DEFAULT, NULL); connp->conn_icmp = icmp; connp->conn_flags = IPCL_RAWIPCONN; connp->conn_proto = IPPROTO_ICMP; icmp->icmp_connp = connp; + rw_init(&icmp->icmp_bpf_lock, NULL, RW_DEFAULT, NULL); rw_init(&connp->conn_ilg_lock, NULL, RW_DEFAULT, NULL); connp->conn_ixa = kmem_zalloc(sizeof (ip_xmit_attr_t), kmflags); if (connp->conn_ixa == NULL) return (ENOMEM); connp->conn_ixa->ixa_refcnt = 1;
*** 2114,2123 **** --- 2139,2149 ---- ASSERT(icmp->icmp_connp == connp); ASSERT(connp->conn_icmp == icmp); mutex_destroy(&connp->conn_lock); cv_destroy(&connp->conn_cv); rw_destroy(&connp->conn_ilg_lock); + rw_destroy(&icmp->icmp_bpf_lock); /* Can be NULL if constructor failed */ if (connp->conn_ixa != NULL) { ASSERT(connp->conn_ixa->ixa_refcnt == 1); ASSERT(connp->conn_ixa->ixa_ire == NULL);