@@ -192,11 +192,21 @@ OvsCtEntryCreate(PNET_BUFFER_LIST curNbl,
192192 }
193193
194194 state |= OVS_CS_F_NEW ;
195+ POVS_CT_ENTRY parentEntry = NULL ;
196+ parentEntry = OvsCtRelatedLookup (ctx -> key , currentTime );
197+ if (parentEntry != NULL ) {
198+ state |= OVS_CS_F_RELATED ;
199+ }
200+
195201 if (commit ) {
196202 entry = OvsConntrackCreateTcpEntry (tcp , curNbl , currentTime );
197203 if (!entry ) {
198204 return NULL ;
199205 }
206+ /* If this is related entry, then update parent */
207+ if (parentEntry != NULL ) {
208+ entry -> parent = parentEntry ;
209+ }
200210 OvsCtAddEntry (entry , ctx , currentTime );
201211 }
202212
@@ -492,6 +502,13 @@ OvsCtSetupLookupCtx(OvsFlowKey *flowKey,
492502 return NDIS_STATUS_SUCCESS ;
493503}
494504
505+ static __inline BOOLEAN
506+ OvsDetectFtpPacket (OvsFlowKey * key ) {
507+ return (key -> ipKey .nwProto == IPPROTO_TCP &&
508+ (ntohs (key -> ipKey .l4 .tpDst ) == IPPORT_FTP ||
509+ ntohs (key -> ipKey .l4 .tpSrc ) == IPPORT_FTP ));
510+ }
511+
495512/*
496513 *----------------------------------------------------------------------------
497514 * OvsProcessConntrackEntry
@@ -542,6 +559,21 @@ OvsProcessConntrackEntry(PNET_BUFFER_LIST curNbl,
542559 break ;
543560 }
544561 }
562+
563+ if (key -> ipKey .nwProto == IPPROTO_TCP && entry ) {
564+ /* Update the related bit if there is a parent */
565+ if (entry -> parent ) {
566+ state |= OVS_CS_F_RELATED ;
567+ } else {
568+ POVS_CT_ENTRY parentEntry ;
569+ parentEntry = OvsCtRelatedLookup (ctx -> key , currentTime );
570+ if (parentEntry != NULL ) {
571+ entry -> parent = parentEntry ;
572+ state |= OVS_CS_F_RELATED ;
573+ }
574+ }
575+ }
576+
545577 /* Copy mark and label from entry into flowKey. If actions specify
546578 different mark and label, update the flowKey. */
547579 if (entry != NULL ) {
@@ -592,7 +624,8 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
592624 BOOLEAN commit ,
593625 UINT16 zone ,
594626 MD_MARK * mark ,
595- MD_LABELS * labels )
627+ MD_LABELS * labels ,
628+ PCHAR helper )
596629{
597630 NDIS_STATUS status = NDIS_STATUS_SUCCESS ;
598631 POVS_CT_ENTRY entry = NULL ;
@@ -629,6 +662,17 @@ OvsCtExecute_(PNET_BUFFER_LIST curNbl,
629662 OvsConntrackSetLabels (key , entry , & labels -> value , & labels -> mask );
630663 }
631664
665+ if (entry && OvsDetectFtpPacket (key )) {
666+ /* FTP parser will always be loaded */
667+ UNREFERENCED_PARAMETER (helper );
668+
669+ status = OvsCtHandleFtp (curNbl , key , layers , currentTime , entry ,
670+ (ntohs (key -> ipKey .l4 .tpDst ) == IPPORT_FTP ));
671+ if (status != NDIS_STATUS_SUCCESS ) {
672+ OVS_LOG_ERROR ("Error while parsing the FTP packet" );
673+ }
674+ }
675+
632676 NdisReleaseRWLock (ovsConntrackLockObj , & lockState );
633677
634678 return status ;
@@ -651,6 +695,8 @@ OvsExecuteConntrackAction(PNET_BUFFER_LIST curNbl,
651695 UINT16 zone = 0 ;
652696 MD_MARK * mark = NULL ;
653697 MD_LABELS * labels = NULL ;
698+ PCHAR helper = NULL ;
699+
654700 NDIS_STATUS status ;
655701
656702 status = OvsDetectCtPacket (key );
@@ -674,9 +720,20 @@ OvsExecuteConntrackAction(PNET_BUFFER_LIST curNbl,
674720 if (ctAttr ) {
675721 labels = NlAttrGet (ctAttr );
676722 }
723+ ctAttr = NlAttrFindNested (a , OVS_CT_ATTR_HELPER );
724+ if (ctAttr ) {
725+ helper = NlAttrGetString (ctAttr );
726+ if (helper == NULL ) {
727+ return NDIS_STATUS_INVALID_PARAMETER ;
728+ }
729+ if (strcmp ("ftp" , helper ) != 0 ) {
730+ /* Only support FTP */
731+ return NDIS_STATUS_NOT_SUPPORTED ;
732+ }
733+ }
677734
678735 status = OvsCtExecute_ (curNbl , key , layers ,
679- commit , zone , mark , labels );
736+ commit , zone , mark , labels , helper );
680737 return status ;
681738}
682739
0 commit comments