ip6_input.c revision a5407c02d5ed61b29481b9b71f1307d7ebec9e5c
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved 2N/A/* Copyright (c) 1990 Mentat Inc. */ 2N/A * Direct read side procedure capable of dealing with chains. GLDv3 based 2N/A * drivers call this function directly with mblk chains while STREAMS 2N/A * read side procedure ip_rput() calls this for single packet with ip_ring 2N/A * set to NULL to process one packet at a time. 2N/A * The ill will always be valid if this function is called directly from 2N/A * If ip_input_v6() is called from GLDv3: 2N/A * - This must be a non-VLAN IP stream. 2N/A * - 'mp' is either an untagged or a special priority-tagged packet. 2N/A * - Any VLAN tag that was in the MAC header has been stripped. 2N/A * If the IP header in packet is not 32-bit aligned, every message in the 2N/A * chain will be aligned before further operations. This is required on SPARC 2N/A * ip_accept_tcp_v6() - This function is called by the squeue when it retrieves 2N/A * a chain of packets in the poll mode. The packets have gone through the 2N/A * data link processing but not IP processing. For performance and latency 2N/A * reasons, the squeue wants to process the chain in line instead of feeding 2N/A * it back via ip_input path. 2N/A * We set up the ip_recv_attr_t with IRAF_TARGET_SQP to that ip_fanout_v6 2N/A * will pass back any TCP packets matching the target sqp to 2N/A * ip_input_common_v6 using ira_target_sqp_mp. Other packets are handled by 2N/A * ip_input_v6 and ip_fanout_v6 as normal. 2N/A * The TCP packets that match the target squeue are returned to the caller 2N/A * as a b_next chain after each packet has been prepend with an mblk 2N/A * from ip_recv_attr_to_mblk. 2N/A * Used by ip_input_v6 and ip_accept_tcp_v6 2N/A * The last three arguments are only used by ip_accept_tcp_v6, and mhip is 2N/A * only used by ip_input_v6. 2N/A /* These ones do not change as we loop over packets */ 2N/A /* For ECMP and outbound transmit ring selection */ 2N/A * We try to have a mhip pointer when possible, but 2N/A * it might be NULL in some cases. In those cases we 2N/A * have to assume unicast. 2N/A * Initialize the one-element route cache. 2N/A * We do ire caching from one iteration to 2N/A * another. In the event the packet chain contains 2N/A * all packets from the same dst, this caching saves 2N/A * an ire_route_recursive for each of the succeeding 2N/A * packets in a packet chain. 2N/A /* Loop over b_next */ 2N/A * if db_ref > 1 then copymsg and free original. Packet 2N/A * may be changed and we do not want the other entity 2N/A * who has a reference to this message to trip over the 2N/A * changes. This is a blind change because trying to 2N/A * catch all places that might change the packet is too 2N/A * This corresponds to the fast path case, where we have 2N/A * a chain of M_DATA mblks. We check the db_ref count 2N/A * of only the 1st data block in the mblk chain. There 2N/A * doesn't seem to be a reason why a device driver would 2N/A * send up data with varying db_ref counts in the mblk 2N/A * chain. In any case the Fast path is a private 2N/A * interface, and our drivers don't do such a thing. 2N/A * Given the above assumption, there is no need to walk 2N/A * down the entire mblk chain (which could have a 2N/A * potential performance problem) 2N/A * The "(DB_REF(mp) > 1)" check was moved from ip_rput() 2N/A * to here because of exclusive ip stacks and vnics. 2N/A * Packets transmitted from exclusive stack over vnic 2N/A * can have db_ref > 1 and when it gets looped back to 2N/A * another vnic in a different zone, you have ip_input() 2N/A * getting dblks with db_ref > 1. So if someone 2N/A * complains of TCP performance under this scenario, 2N/A * take a serious look here on the impact of copymsg(). 2N/A * IP header ptr not aligned? 2N/A * OR IP header not complete in first mblk 2N/A /* Protect against a mix of Ethertypes and IP versions */ 2N/A /* mhip might point into 1st packet in the chain. */ 2N/A * Check for Martian addrs; we have to explicitly 2N/A * test for for zero dst since this is also used as 2N/A * an indication that the rtc is not used. 2N/A /* mhip might point into 1st packet in the chain. */ 2N/A * Keep L2SRC from a previous packet in chain since mhip 2N/A * might point into an earlier packet in the chain. 2N/A * We must count all incoming packets, even if they end 2N/A * up being dropped later on. Defer counting bytes until 2N/A * we have the whole IP header in first mblk. 2N/A * ill_input_short_v6 2N/A * The former is used in the case of TX. See ill_set_inputfn(). 2N/A /* Any references to clean up? No hold on ira_ill */ 2N/A /* Better be called from ip_accept_tcp */ 2N/A /* Found one packet to accept */ 2N/A /* mhip might point into 1st packet in the chain. */ 2N/A /* Any remaining references to the route cache? */ 2N/A /* Better be called from ip_accept_tcp */ 2N/A * This input function is used when 2N/A * - is_system_labeled() 2N/A * Note that for IPv6 CGTP filtering is handled only when receiving fragment 2N/A * headers, and RSVP uses router alert options, thus we don't need anything 2N/A * Attach any necessary label information to 2N/A * This updates ira_cred, ira_tsl and ira_free_flags based 2N/A /* Note that ira_tsl can be NULL here. */ 2N/A /* tsol_get_pkt_label sometimes does pullupmsg */ 2N/A * Check for IPv6 addresses that should not appear on the wire 2N/A * as either source or destination. 2N/A * If we ever implement Stateless IPv6 Translators (SIIT) we'd have 2N/A * to revisit the IPv4-mapped part. 2N/A ip1dbg((
"ip_input_v6: pkt with IPv4-mapped addr"));
2N/A ip1dbg((
"ip_input_v6: pkt with loopback addr"));
2N/A * having :: in the src is ok: it's used for DAD. 2N/A ip1dbg((
"ip_input_v6: pkt with unspecified addr"));
2N/A * Routing lookup for IPv6 link-locals. 2N/A * First we look on the inbound interface, then we check for IPMP and 2N/A * look on the upper interface. 2N/A * We update ira_ruifindex if we find the IRE on the upper interface. 2N/A * When we are using IMP we need to look for an IRE on both the 2N/A * under and upper interfaces since there are different 2N/A * link-local addresses for the under and upper. 2N/A * This is the tail-end of the full receive side packet handling. 2N/A * It can be used directly when the configuration is simple. 2N/A * v4mapped. All of them start with a 64 bits of zero. 2N/A ip1dbg((
"ip_input_v6: pkt with bad src addr\n"));
2N/A ip1dbg((
"ip_input_v6: pkt with bad dst addr\n"));
2N/A /* multiple mblk or too short */ 2N/A * The event for packets being received from a 'physical' 2N/A * interface is placed after validation of the source and/or 2N/A * destination address as being local so that packets can be 2N/A * redirected to loopback addresses using ipnat. 2N/A /* The length could have changed */ 2N/A * In case the destination changed we override any previous 2N/A * change to nexthop. 2N/A * On the inbound path the src zone will be unknown as 2N/A * this packet has come from the wire. 2N/A * For IPv6 we update ira_ip_hdr_length and ira_protocol as 2N/A * we parse the headers, starting with the hop-by-hop options header. 2N/A * Update ira_ip_hdr_length to skip the hop-by-hop header 2N/A * once we get to ip_fanout_v6 2N/A * Packet has been consumed and any 2N/A * needed ICMP messages sent. 2N/A /* no action needed */ 2N/A * Known router alert. Make use handle it as local 2N/A * by setting the nexthop to be the all-host multicast 2N/A * address, and skip multicast membership filter by 2N/A * marking as a router alert. 2N/A * Here we check to see if we machine is setup as 2N/A * L3 loadbalancer and if the incoming packet is for a VIP 2N/A * Check the following: 2N/A * - there is at least a rule 2N/A * - protocol of the packet is supported 2N/A * We don't load balance IPv6 link-locals. 2N/A /* For convenience, we just pull up the mblk. */ 2N/A /* Set the dst to that of the chosen server */ 2N/A /* Can not use route cache with TX since the labels can differ */ 2N/A /* Match destination and label */ 2N/A /* Update the route cache so we do the ire_refrele */ 2N/A /* Use the route cache */ 2N/A /* Update the route cache */ 2N/A * Based on ire_type and ire_flags call one of: 2N/A * ire_recv_local_v6 - for IRE_LOCAL 2N/A * ire_recv_loopback_v6 - for IRE_LOOPBACK 2N/A * ire_recv_multirt_v6 - if RTF_MULTIRT 2N/A * ire_recv_noroute_v6 - if RTF_REJECT or RTF_BLACHOLE 2N/A * ire_recv_multicast_v6 - for IRE_MULTICAST 2N/A * ire_recv_noaccept_v6 - for ire_noaccept ones 2N/A * ire_recv_forward_v6 - for the rest. 2N/A * ire_recvfn for IREs that need forwarding 2N/A * Either ire_nce_capable or ire_dep_parent would be set for the IRE 2N/A * when it is found by ire_route_recursive, but that some other thread 2N/A * could have changed the routes with the effect of clearing 2N/A * ire_dep_parent. In that case we'd end up dropping the packet, or 2N/A * finding a new nce below. 2N/A * Get, allocate, or update the nce. 2N/A * We get a refhold on ire_nce_cache as a result of this to avoid races 2N/A * where ire_nce_cache is deleted. 2N/A * This ensures that we don't forward if the interface is down since 2N/A * ipif_down removes all the nces. 2N/A /* Not yet set up - try to set one up */ 2N/A /* The ire_dep_parent chain went bad, or no memory */ 2N/A * Unless we are forwarding, drop the packet. 2N/A * Unlike IPv4 we don't allow source routed packets out the same 2N/A * interface when we are not a router. 2N/A * Note that ill_forward_set() will set the ILLF_ROUTER on 2N/A * all the group members when it gets an ipmp-ill or under-ill. 2N/A * Should only use IREs that are visible from the 2N/A * global zone for forwarding. 2N/A * For IPv6 any source route would have already been 2N/A * advanced in ip_fanout_v6 2N/A * ipIfStatsHCInForwDatagrams should only be increment if there 2N/A * will be an attempt to forward the packet, which is why we 2N/A * increment after the above condition has been checked. 2N/A /* Initiate Read side IPPF processing */ 2N/A /* ip_process translates an IS_UNDER_IPMP */ 2N/A /* ip_drop_packet and MIB done */ 2N/A "during IPPF processing\n"));
2N/A * Even if the destination was changed by the filter we use the 2N/A * forwarding decision that was made based on the address 2N/A /* Might have changed */ 2N/A /* Packet is being forwarded. Turning off hwcksum flag. */ 2N/A * Per RFC 3513 section 2.5.2, we must not forward packets with 2N/A * an unspecified source address. 2N/A * The loopback address check for both src and dst has already 2N/A * been checked in ip_input_v6 2N/A * In the future one can envision adding RPF checks using number 3. 2N/A * Check to see if we're forwarding the packet to a 2N/A * different link from which it came. If so, check the 2N/A * source and destination addresses since routers must not 2N/A * forward any packets with link-local source or 2N/A * destination addresses to other links. Otherwise (if 2N/A * we're forwarding onto the same link), conditionally send 2N/A * a redirect message. 2N/A /* TBD add site-local check at site boundary? */ 2N/A * CIPSO options as needed. 2N/A * Size may have changed. Remember amount added in case 2N/A * ip_fragment needs to send an ICMP too big. 2N/A * Used for sending out unicast and multicast packets that are 2N/A /* Initiate Write side IPPF processing before any fragmentation */ 2N/A /* ip_process translates an IS_UNDER_IPMP */ 2N/A /* ip_drop_packet and MIB done */ 2N/A " during IPPF processing\n"));
2N/A * Remove any CIPSO option added by 2N/A * tsol_ip_forward, and make sure we report 2N/A * a path MTU so that there 2N/A * is room to add such a CIPSO option for future 2N/A * IXAF_NO_LOOP_ZONEID is not set hence 6th arg 2N/A * ire_recvfn for RTF_REJECT and RTF_BLACKHOLE routes, including IRE_NOROUTE, 2N/A * which is what ire_route_recursive returns when there is no matching ire. 2N/A * Send ICMP unreachable unless blackhole. 2N/A /* Would we have forwarded this packet if we had a route? */ 2N/A * If we had a route this could have been forwarded. Count as such. 2N/A * ipIfStatsHCInForwDatagrams should only be increment if there 2N/A * will be an attempt to forward the packet, which is why we 2N/A * increment after the above condition has been checked. 2N/A * ire_recvfn for IRE_LOCALs marked with ire_noaccept. Such IREs are used for 2N/A * VRRP when in noaccept mode. 2N/A * We silently drop packets except for Neighbor Solicitations and 2N/A * Neighbor Advertisements. 2N/A * ire_recvfn for IRE_MULTICAST. 2N/A /* Tag for higher-level protocols */ 2N/A * So that we don't end up with dups, only one ill an IPMP group is 2N/A * nominated to receive multicast traffic. 2N/A * If we have no cast_ill we are liberal and accept everything. 2N/A /* For an under ill_grp can change under lock */ 2N/A * We switch to the upper ill so that mrouter and hasmembers 2N/A * can operate on upper here and in ip_input_multicast. 2N/A * Check if we are a multicast router - send ip_mforward a copy of 2N/A * Due to mroute_decap tunnels we consider forwarding packets even if 2N/A * mrouted has not joined the allmulti group on this interface. 2N/A * Clear the indication that this may have hardware 2N/A * checksum as we are not using it for forwarding. 2N/A * ip_mforward helps us make these distinctions: If received 2N/A * on tunnel and not IGMP, then drop. 2N/A * If IGMP packet, then don't check membership 2N/A * If received on a phyint and IGMP or PIM, then 2N/A * don't check membership 2N/A /* ip_mforward updates mib variables if needed */ 2N/A * pkt is okay and arrived on phyint. 2N/A /* pkt is mal-formed, toss it */ 2N/A * pkt is okay and arrived on a tunnel 2N/A * If we are running a multicast router 2N/A * we need to see all mld packets, which 2N/A * are marked with router alerts. 2N/A * If this was a router alert we skip the group membership check. 2N/A * Check if we have members on this ill. This is not necessary for 2N/A * correctness because even if the NIC/GLD had a leaky filter, we 2N/A * filter before passing to each conn_t. 2N/A * This might just be caused by the fact that 2N/A * multiple IP Multicast addresses map to the same 2N/A * link layer multicast - no need to increment counter! 2N/A ip2dbg((
"ire_recv_multicast_v6: multicast for us\n"));
2N/A * After reassembly and IPsec we will need to duplicate the 2N/A * multicast packet for all matching zones on the ill. 2N/A /* Reassemble on the ill on which the packet arrived */ 2N/A * ire_recvfn for IRE_OFFLINK with RTF_MULTIRT. 2N/A * Drop packets since we don't forward out multirt routes. 2N/A * ire_recvfn for IRE_LOOPBACK. This is only used when a FW_HOOK 2N/A * has rewritten the packet to have a loopback destination address (We 2N/A * filter out packet with a loopback destination from arriving over the wire). 2N/A * We don't know what zone to use, thus we always use the GLOBAL_ZONEID. 2N/A /* Switch to the lo0 ill for further processing */ 2N/A * Update ira_ill to be the ILL on which the IP address 2N/A * No need to hold the ill since we have a hold on the ire 2N/A * ire_recvfn for IRE_LOCAL. 2N/A /* Make a note for DAD that this address is in use */ 2N/A /* Only target the IRE_LOCAL with the right zoneid. */ 2N/A * If the packet arrived on the wrong ill, we check that 2N/A * If it is, then we ensure that we do the reassembly on 2N/A * the ill on which the address is hosted. We keep ira_rill as 2N/A * the one on which the packet arrived, so that IP_PKTINFO and 2N/A * friends can report this. 2N/A * Update ira_ill to be the ILL on which the IP address 2N/A * is hosted. No need to hold the ill since we have a 2N/A * hold on the ire. Note that we do the switch even if 2N/A * new_ire == ire (for IPMP, ire would be the one corresponding 2N/A /* ira_ruifindex tracks the upper for ira_rill */ 2N/A * Common function for packets arriving for the host. Handles 2N/A * checksum verification, reassembly checks, etc. 2N/A * For multicast we need some extra work before 2N/A * we call ip_fanout_v6(), since in the case of shared-IP zones 2N/A * we need to pretend that a packet arrived for each zoneid. 2N/A * Handle multiple zones which want to receive the same multicast packets 2N/A * on this ill by delivering a packet to each of them. 2N/A * Note that for packets delivered to transports we could instead do this 2N/A * as part of the fanout code, but since we need to handle icmp_inbound 2N/A * it is simpler to have multicast work the same as IPv4 broadcast. 2N/A * The ip_fanout matching for multicast matches based on ilm independent of 2N/A * zoneid since the zoneid restriction is applied when joining a multicast 2N/A /* ire_recv_multicast has switched to the upper ill for IPMP */ 2N/A * If we don't have more than one shared-IP zone, or if 2N/A * there are no members in anything but the global zone, 2N/A * then just set the zoneid and proceed. 2N/A /* If sender didn't want this zone to receive it, drop */ 2N/A * Here we loop over all zoneids that have members in the group 2N/A * and deliver a packet to ip_fanout for each zoneid. 2N/A * First find any members in the lowest numeric zoneid by looking for 2N/A * first zoneid larger than -1 (ALL_ZONES). 2N/A * We terminate the loop when we receive -1 (ALL_ZONES). 2N/A * and doing that at the end. 2N/A /* If sender didn't want this zone to receive it, skip */ 2N/A /* Failed to deliver to one zone */ 2N/A * IPsec might have modified ira_pktlen and ira_ip_hdr_length 2N/A * so we restore them for a potential next iteration 2N/A /* Do the main ire */ 2N/A /* If sender didn't want this zone to receive it, drop */ 2N/A * Determine the zoneid and IRAF_TX_MAC_EXEMPTABLE if trusted extensions 2N/A * is in use. Updates ira_zoneid and ira_flags as a result. 2N/A * If the packet is unlabeled we might allow read-down 2N/A * for MAC_EXEMPT. Below we clear this if it is a multi-level 2N/A * Note that ira_tsl can be NULL here. 2N/A /* Caller ensures this */ 2N/A * Only these transports support MLP. 2N/A * We know their destination port numbers is in 2N/A * the same place in the header. 2N/A * No need to handle exclusive-stack zones 2N/A * since ALL_ZONES only applies to the shared IP instance. 2N/A * If no shared MLP is found, tsol_mlp_findzone returns 2N/A * ALL_ZONES. In that case, we assume it's SLP, and 2N/A * search for the zone based on the packet label. 2N/A * If there is such a zone, we prefer to find a 2N/A * connection in it. Otherwise, we look for a 2N/A * MAC-exempt connection in any zone whose label 2N/A * dominates the default label on the packet. 2N/A /* Handle shared address for other protocols */ 2N/A * Increment checksum failure statistics 2N/A/* Calculate the IPv6 pseudo-header checksum for TCP, UDP, and ICMPV6 */ 2N/A /* Protocol and length */ 2N/A /* Protocol and length */ 2N/A /* Protocol and length */ 2N/A * Software verification of the ULP checksums. 2N/A * Returns B_TRUE if ok. 2N/A * Increments statistics of failed. 2N/A * Verify the ULP checksums. 2N/A * Returns B_TRUE if ok, or if the ULP doesn't have a well-defined checksum 2N/A * Increments statistics if failed. 2N/A * Before going through the regular checksum 2N/A * calculation, make sure the received checksum 2N/A * is non-zero. RFC 2460 says, a 0x0000 checksum 2N/A * in a UDP packet (within IPv6 packet) is invalid 2N/A * and should be replaced by 0xffff. This makes 2N/A * sense as regular checksum calculation will 2N/A * pass for both the cases i.e. 0x0000 and 0xffff. 2N/A * Removing one of the case makes error detection 2N/A /* 0x0000 checksum is invalid */ 2N/A * Defer until later whether a bad checksum is ok 2N/A * in order to allow RAW sockets to use Adler checksum 2N/A /* No ULP checksum to verify. */ 2N/A * Revert to software checksum calculation if the interface 2N/A * isn't capable of checksum offload. 2N/A * We clear DB_CKSUMFLAGS when going through IPsec in ip_fanout. 2N/A * Note: IRAF_NO_HW_CKSUM is not currently used. 2N/A * We apply this for all ULP protocols. Does the HW know to 2N/A * not set the flags for SCTP and other protocols. 2N/A * Hardware has already verified the checksum. 2N/A * Full checksum has been computed by the hardware 2N/A * and has been attached. If the driver wants us to 2N/A * verify the correctness of the attached value, in 2N/A * order to protect against faulty hardware, compare 2N/A * it against -0 (0xFFFF) to see if it's valid. 2N/A * Partial checksum has been calculated by hardware 2N/A * and attached to the packet; in addition, any 2N/A * prepended extraneous data is even byte aligned, 2N/A * and there are at most two mblks associated with 2N/A * the packet. If any such data exists, we adjust 2N/A * the checksum; also take care any postpended data. 2N/A * One's complement subtract extraneous checksum * Handle fanout of received packets. * Unicast packets that are looped back (from ire_send_local_v6) and packets * from the wire are differentiated by checking IRAF_VERIFY_ULP_CKSUM. * Before sending it to the client, invoke IPPF processing. Policy processing * takes place only if the callout_position, IPP_LOCAL_IN, is enabled. * We repeat this as we parse over destination options header and * fragment headers (earlier we've handled any hop-by-hop options * We update ira_protocol and ira_ip_hdr_length as we skip past * the intermediate headers; they already point past any * Time for IPP once we've done reassembly and IPsec. * We skip this for loopback packets since we don't do IPQoS * Use the interface on which the packet arrived - not where * the IP address is hosted. /* ip_process translates an IS_UNDER_IPMP */ /* ip_drop_packet and MIB done */ /* Determine the minimum required size of the upper-layer header */ /* Need to do this for at least the set of ULPs that TX handles. */ /* Make sure we have the min ULP header length */ * If trusted extensions then determine the zoneid and TX specific /* This can update ira->ira_flags and ira->ira_zoneid */ /* Verify ULP checksum. Handles TCP, UDP, and SCTP */ /* Bad checksum. Stats are already incremented */ /* IRAF_SCTP_CSUM_ERR could have been set */ /* For TCP, discard multicast packets. */ /* First mblk contains IP+TCP headers per above check */ /* TCP options present? */ * There must be TCP options. * Make sure we can grab them. * Pass up a squeue hint to tcp. * If ira_sqp is already set (this is loopback) we leave it /* Look for AF_INET or AF_INET6 that matches */ /* Note that mp is NULL */ /* Found a client; up it goes */ /* Not TCP; must be SOCK_RAW, IPPROTO_TCP */ * We do different processing whether called from * ip_accept_tcp and we match the target, don't match * the target, and when we are called by ip_input. * Conn ref release when drained from /* For SCTP, discard multicast packets. */ * Since there is no SCTP h/w cksum support yet, just /* Length ensured above */ * No potential sctp checksum errors go to the Sun * sctp stack however they might be Adler-32 summed * packets a userland stack bound to a raw IP socket * could reasonably use. Note though that Adler-32 is * a long deprecated algorithm and customer sctp * networks should eventually migrate to CRC-32 at * which time this facility should be removed. /* Check for raw socket or OOTB handling */ /* Check for raw socket or OOTB handling */ /* Found a client; up it goes */ /* sctp_input does a rele of the sctp_t */ /* First mblk contains IP+UDP headers as checked above */ uint16_t *
up;
/* Pointer to ports in ULP header */ /* Look for AF_INET or AF_INET6 that matches */ /* Note that mp is NULL */ /* Found a client; up it goes */ * Clear hardware checksumming flag as it is currently only /* Check variable for testing applications */ * We need to accomodate icmp messages coming in clear * until we get everything secure from the wire. If * icmp_accept_clear_messages is zero we check with * the global policy and act accordingly. If it is * non-zero, we accept the message without any checks. * But *this does not mean* that this will be delivered * to RAW socket clients. By accepting we might send * replies back, change our MTU value etc., * but delivery to the ULP/clients depends on their * On a labeled system, we have to check whether the zone * itself is permitted to receive raw traffic. /* No need to pass to RAW sockets */ /* We already check for MIN_EHDR_LEN above */ /* Check if AH is present and needs to be processed. */ * Reinitialize pointers, as ipsec_early_ah_v6() does * complete pullups. We don't have to do more pullups * Update ira_ip_hdr_length to skip the destination header * Note: XXX This code does not seem to make * distinction between Destination Options Header * happen if we are at the end of source route. * This may become significant in future. * (No real significant Destination Options are * Packet has been consumed and any needed /* No action needed continue */ * Unnexpected return value * (Router alert is a Hop-by-Hop option) panic(
"ip_fanout_v6: router " "alert hbh opt indication in dest opt");
* Invoke the CGTP (multirouting) filtering module to * process the incoming packet. Packets identified as * duplicates must be discarded. Filtering is active * only if the ip_cgtp_filter ndd variable is * CGTP and IPMP are mutually exclusive so * phyint_ifindex is fine here. * Update ip_hdr_length to skip the frag header * ip_input_fragment_v6 will determine the extension header * prior to the fragment header and update its nexthdr value, * and also set ira_protocol to the nexthdr that follows the * Make sure we have ira_l2src before we loose the original /* Reassembly is still pending */ * The mblk chain has the frag header removed and * ira_protocol, ira_pktlen, ira_ip_hdr_length as well as the * IP header has been updated to refleact the result. * Illegal header sequence. * (Hop-by-hop headers are processed above * and required to immediately follow IPv6 header) /* Check if AH is present and needs to be processed. */ * Reinitialize pointers, as ipsec_early_ah_v6() does * complete pullups. We don't have to do more pullups /* Not end of source route */ /* select inbound SA and have IPsec process the pkt */ * Either it failed or is pending. In the former case * ipIfStatsInDiscards was increased. /* we're done with IPsec processing, send it up */ /* All processing is done. Count as "delivered". */ /* iptun will verify trusted label */ * On a labeled system, we have to check whether the zone * itself is permitted to receive raw traffic. * The above input functions may have returned the pulled up message. * So ip6h need to be reinitialized. /* No user-level listener for these packets packets */ * Handle fanout to raw sockets. There * can be more than one stream bound to a particular * protocol. When this is the case, each one gets a copy * of any incoming packets.