@@ -1011,17 +1011,41 @@ void mpl_clear_realm_scope_seeds(protocol_interface_info_entry_t *cur)
10111011static buffer_t * mpl_exthdr_provider (buffer_t * buf , ipv6_exthdr_stage_t stage , int16_t * result )
10121012{
10131013 mpl_domain_t * domain = mpl_domain_lookup_with_realm_check (buf -> interface , buf -> dst_sa .address );
1014- if (!domain ) {
1015- // We need to tunnel
10161014
1017- if (stage != IPV6_EXTHDR_MODIFY ) {
1018- * result = 0 ;
1015+ /* Deal with simpler modify-already-created-header case first. Note that no error returns. */
1016+ if (stage == IPV6_EXTHDR_MODIFY ) {
1017+ if (!domain ) {
1018+ * result = IPV6_EXTHDR_MODIFY_TUNNEL ;
1019+ memcpy (buf -> dst_sa .address , ADDR_ALL_MPL_FORWARDERS , 16 );
1020+ buf -> src_sa .addr_type = ADDR_NONE ; // force auto-selection
10191021 return buf ;
10201022 }
10211023
1022- * result = IPV6_EXTHDR_MODIFY_TUNNEL ;
1023- memcpy (buf -> dst_sa .address , ADDR_ALL_MPL_FORWARDERS , 16 );
1024- buf -> src_sa .addr_type = ADDR_NONE ; // force auto-selection
1024+ if (buf -> options .ip_extflags & IPEXT_HBH_MPL_UNFILLED ) {
1025+ /* We assume we created this, therefore our option is in place
1026+ * in the expected place. Sequence is set now, AFTER
1027+ * fragmentation.
1028+ */
1029+ uint8_t * iphdr = buffer_data_pointer (buf );
1030+ uint8_t * ext = iphdr + IPV6_HDRLEN ;
1031+ if (iphdr [IPV6_HDROFF_NH ] != IPV6_NH_HOP_BY_HOP || ext [2 ] != IPV6_OPTION_MPL ) {
1032+ tr_err ("modify" );
1033+ return buffer_free (buf );
1034+ }
1035+ /* We don't bother setting the M flag on these initial packets. Setting to 0 is always acceptable. */
1036+ ext [5 ] = domain -> sequence ++ ;
1037+ buf -> options .ip_extflags &=~ IPEXT_HBH_MPL_UNFILLED ;
1038+ buf -> mpl_option_data_offset = IPV6_HDRLEN + 4 ;
1039+ mpl_forwarder_process_message (buf , domain , true);
1040+ }
1041+ * result = 0 ;
1042+ return buf ;
1043+ }
1044+
1045+ /* Rest of code deals with header insertion */
1046+ if (!domain ) {
1047+ // We will need to tunnel - do nothing on the inner packet
1048+ * result = 0 ;
10251049 return buf ;
10261050 }
10271051
@@ -1112,26 +1136,6 @@ static buffer_t *mpl_exthdr_provider(buffer_t *buf, ipv6_exthdr_stage_t stage, i
11121136 buf -> options .ip_extflags |= IPEXT_HBH_MPL | IPEXT_HBH_MPL_UNFILLED ;
11131137 return buf ;
11141138 }
1115- case IPV6_EXTHDR_MODIFY :
1116- if (buf -> options .ip_extflags & IPEXT_HBH_MPL_UNFILLED ) {
1117- /* We assume we created this, therefore our option is in place
1118- * in the expected place. Sequence is set now, AFTER
1119- * fragmentation.
1120- */
1121- uint8_t * iphdr = buffer_data_pointer (buf );
1122- uint8_t * ext = iphdr + IPV6_HDRLEN ;
1123- if (iphdr [IPV6_HDROFF_NH ] != IPV6_NH_HOP_BY_HOP || ext [2 ] != IPV6_OPTION_MPL ) {
1124- tr_err ("modify" );
1125- return buffer_free (buf );
1126- }
1127- /* We don't bother setting the M flag on these initial packets. Setting to 0 is always acceptable. */
1128- ext [5 ] = domain -> sequence ++ ;
1129- buf -> options .ip_extflags &=~ IPEXT_HBH_MPL_UNFILLED ;
1130- buf -> mpl_option_data_offset = IPV6_HDRLEN + 4 ;
1131- mpl_forwarder_process_message (buf , domain , true);
1132- }
1133- * result = 0 ;
1134- return buf ;
11351139 default :
11361140 return buffer_free (buf );
11371141 }
0 commit comments