Print this page
dccp: ips_ipcl_dccp_fanout
@@ -114,10 +114,11 @@
#include <sys/pattr.h>
#include <inet/ipclassifier.h>
#include <inet/sctp_ip.h>
#include <inet/sctp/sctp_impl.h>
#include <inet/udp_impl.h>
+#include <inet/dccp_impl.h>
#include <sys/sunddi.h>
#include <sys/tsol/label.h>
#include <sys/tsol/tnet.h>
@@ -2387,10 +2388,13 @@
min_ulp_header_length = UDPH_SIZE;
break;
case IPPROTO_ICMP:
min_ulp_header_length = ICMPH_SIZE;
break;
+ case IPPROTO_DCCP:
+ min_ulp_header_length = DCCP_MIN_HEADER_LENGTH;
+ break;
default:
min_ulp_header_length = 0;
break;
}
/* Make sure we have the min ULP header length */
@@ -2712,10 +2716,73 @@
(connp->conn_recv)(connp, mp, NULL, ira);
CONN_DEC_REF(connp);
ira->ira_ill = ill;
ira->ira_rill = rill;
return;
+ case IPPROTO_DCCP:
+ /* For DCCP, discard broadcast and multicast packets */
+ if (iraflags & IRAF_MULTIBROADCAST) {
+ goto discard;
+ }
+
+ /* First mblk contains IP+DCCP headers per above check */
+ ASSERT(len >= ip_hdr_length + DCCP_MIN_HEADER_LENGTH);
+
+ /* Squeue hint */
+ if (ira->ira_sqp == NULL) {
+ ira->ira_sqp = ip_squeue_get(ira->ira_ring);
+ }
+
+ connp = ipcl_classify_v4(mp, IPPROTO_DCCP, ip_hdr_length,
+ ira, ipst);
+ if (connp == NULL) {
+ cmn_err(CE_NOTE, "ip_input.c: ip_fanout_v4 connp not found");
+ /* Send the reset packet */
+ BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInDelivers);
+ dccp_xmit_listeners_reset(mp, ira, ipst, NULL);
+ return;
+ }
+
+ if (connp->conn_incoming_ifindex != 0 &&
+ connp->conn_incoming_ifindex != ira->ira_ruifindex) {
+ cmn_err(CE_NOTE, "ip_input.c: ip_fanout_v4 ifindex problem");
+ /* Send the reset packet */
+ BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInDelivers);
+ dccp_xmit_listeners_reset(mp, ira, ipst, NULL);
+ return;
+ }
+
+ if (CONN_INBOUND_POLICY_PRESENT(connp, ipss) ||
+ (iraflags & IRAF_IPSEC_SECURE)) {
+ mp = ipsec_check_inbound_policy(mp, connp,
+ ipha, NULL, ira);
+ if (mp == NULL) {
+ BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
+ /* Note that mp is NULL */
+ ip_drop_input("ipIfStatsInDiscards", mp, ill);
+ CONN_DEC_REF(connp);
+ return;
+ }
+ }
+
+ /* Found a client; up it goes */
+ BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInDelivers);
+ ira->ira_ill = ira->ira_rill = NULL;
+
+ /* XXX SOCK_RAW for DCCP? */
+
+ if (iraflags & IRAF_TARGET_SQP) {
+ cmn_err(CE_NOTE, "IRAF_TARGET_SQP");
+ } else {
+ SQUEUE_ENTER_ONE(connp->conn_sqp, mp, connp->conn_recv,
+ connp, ira, ip_squeue_flag, SQTAG_IP_DCCP_INPUT);
+ }
+
+ ira->ira_ill = ill;
+ ira->ira_rill = rill;
+ return;
+
default:
break;
}
/*