@@ -60,6 +60,7 @@ typedef struct {
6060 int8_t interface_id ;
6161 uint8_t server_address [16 ];
6262 bool relay_activated ;
63+ bool add_interface_id_option ;
6364 ns_list_link_t link ;
6465} relay_instance_t ;
6566typedef NS_LIST_HEAD (relay_instance_t , link ) relay_instance_list_t ;
@@ -83,6 +84,8 @@ typedef struct {
8384 uint8_t * msg_ptr ;
8485 uint16_t msg_len ;
8586 uint8_t * relay_start ;
87+ uint8_t * opt_interface_id ;
88+ uint16_t opt_interface_id_length ;
8689 ns_list_link_t link ;
8790} msg_tr_t ;
8891typedef NS_LIST_HEAD (msg_tr_t , link ) tr_list_t ;
@@ -335,6 +338,8 @@ void recv_dhcp_server_msg(void *cb_res)
335338 }
336339 //Update Source and data
337340 msg_tr_ptr -> relay_start = msg_ptr ;
341+ msg_tr_ptr -> opt_interface_id = relay_msg .relay_interface_id .msg_ptr ;
342+ msg_tr_ptr -> opt_interface_id_length = relay_msg .relay_interface_id .len ;
338343 memcpy (msg_tr_ptr -> addr .address , relay_msg .peer_address , 16 );
339344 msg_ptr = relay_msg .relay_options .msg_ptr ;
340345 msg_len = relay_msg .relay_options .len ;
@@ -408,35 +413,37 @@ void recv_dhcp_relay_msg(void *cb_res)
408413 }
409414 ns_address_t src_address ;
410415
411- uint8_t relay_frame [ DHCPV6_RELAY_LENGTH + 4 ];
412- ns_iovec_t msg_iov [ 2 ];
413- msg_iov [ 0 ]. iov_base = relay_frame ;
414- msg_iov [ 0 ]. iov_len = 34 ;
415- msg_iov [ 1 ]. iov_base = ns_dyn_mem_temporary_alloc (sckt_data -> d_len );
416- msg_iov [ 1 ]. iov_len = sckt_data -> d_len ;
417- if (msg_iov [ 1 ]. iov_base == NULL ) {
416+ //Relay vector added space for relay frame + Interface ID
417+ uint8_t relay_frame [ DHCPV6_RELAY_LENGTH + 4 + 5 ];
418+
419+
420+ uint8_t * socket_data = ns_dyn_mem_temporary_alloc (sckt_data -> d_len );
421+
422+ if (socket_data == NULL ) {
418423 // read actual message
419424 tr_error ("Out of resources" );
420425 goto cleanup ;
421426 }
422427
428+
423429 ns_msghdr_t msghdr ;
430+ ns_iovec_t msg_data ;
431+ msg_data .iov_base = socket_data ;
432+ msg_data .iov_len = sckt_data -> d_len ;
424433 //Set messages name buffer
425434 msghdr .msg_name = & src_address ;
426435 msghdr .msg_namelen = sizeof (src_address );
427- msghdr .msg_iov = & msg_iov [ 1 ] ;
436+ msghdr .msg_iov = & msg_data ;
428437 msghdr .msg_iovlen = 1 ;
429438 msghdr .msg_control = NULL ;
430439 msghdr .msg_controllen = 0 ;
431440
432441 msg_len = socket_recvmsg (sckt_data -> socket_id , & msghdr , NS_MSG_LEGACY0 );
433442
434-
435443 tr_debug ("dhcp Relay recv msg" );
436444
437445 //Parse type
438- uint8_t * ptr = msg_iov [1 ].iov_base ;
439- uint8_t msg_type = * ptr ;
446+ uint8_t msg_type = * socket_data ;
440447
441448 int16_t tc = 0 ;
442449 if (msg_type == DHCPV6_RELAY_FORWARD ) {
@@ -446,7 +453,7 @@ void recv_dhcp_relay_msg(void *cb_res)
446453 } else if (msg_type == DHCPV6_RELAY_REPLY ) {
447454 //Parse and validate Relay
448455 dhcpv6_relay_msg_t relay_msg ;
449- if (!libdhcpv6_relay_msg_read (ptr , msg_len , & relay_msg )) {
456+ if (!libdhcpv6_relay_msg_read (socket_data , msg_len , & relay_msg )) {
450457 tr_error ("Not valid relay" );
451458 goto cleanup ;
452459 }
@@ -458,14 +465,14 @@ void recv_dhcp_relay_msg(void *cb_res)
458465 memcpy (src_address .address , relay_msg .peer_address , 16 );
459466 src_address .type = ADDRESS_IPV6 ;
460467 src_address .identifier = DHCPV6_CLIENT_PORT ;
461- msghdr .msg_iov = & msg_iov [ 0 ] ;
468+ msghdr .msg_iov = & msg_data ;
462469 msghdr .msg_iovlen = 1 ;
463- msg_iov [ 0 ] .iov_base = relay_msg .relay_options .msg_ptr ;
464- msg_iov [ 0 ] .iov_len = relay_msg .relay_options .len ;
470+ msg_data .iov_base = relay_msg .relay_options .msg_ptr ;
471+ msg_data .iov_len = relay_msg .relay_options .len ;
465472 tr_debug ("Forward Original relay msg to client" );
466473
467474 } else {
468- if (0 != libdhcpv6_message_malformed_check (ptr , msg_len )) {
475+ if (0 != libdhcpv6_message_malformed_check (socket_data , msg_len )) {
469476 tr_error ("Malformed packet" );
470477 goto cleanup ;
471478 }
@@ -476,10 +483,24 @@ void recv_dhcp_relay_msg(void *cb_res)
476483 tr_error ("No GP address" );
477484 goto cleanup ;
478485 }
479-
486+ ns_iovec_t msg_iov [2 ];
487+ uint8_t * ptr = relay_frame ;
480488 //Build
481- libdhcpv6_dhcp_relay_msg_write (relay_frame , DHCPV6_RELAY_FORWARD , 0 , src_address .address , gp_address );
482- libdhcpv6_dhcp_option_header_write (relay_frame + 34 , msg_len );
489+ //ADD relay frame vector front of original data
490+ msghdr .msg_iov = & msg_iov [0 ];
491+ msg_iov [0 ].iov_base = relay_frame ;
492+ msghdr .msg_iovlen = 2 ;
493+ //SET Original Data
494+ msg_iov [1 ].iov_base = socket_data ;
495+ msg_iov [1 ].iov_len = msg_len ;
496+
497+ ptr = libdhcpv6_dhcp_relay_msg_write (ptr , DHCPV6_RELAY_FORWARD , 0 , src_address .address , gp_address );
498+ if (relay_srv -> add_interface_id_option ) {
499+ ptr = libdhcpv6_option_interface_id_write (ptr , sckt_data -> interface_id );
500+ }
501+ ptr = libdhcpv6_dhcp_option_header_write (ptr , DHCPV6_OPTION_RELAY , msg_len );
502+ //Update length of relay vector
503+ msg_iov [0 ].iov_len = ptr - relay_frame ;
483504
484505 //Update Neighbour table if necessary
485506 relay_notify_t * neigh_notify = dhcp_service_notify_find (sckt_data -> interface_id );
@@ -491,20 +512,14 @@ void recv_dhcp_relay_msg(void *cb_res)
491512 memcpy (src_address .address , relay_srv -> server_address , 16 );
492513 src_address .type = ADDRESS_IPV6 ;
493514 src_address .identifier = DHCPV6_SERVER_PORT ;
494- //ADD relay frame vector front of original data
495- msghdr .msg_iov = & msg_iov [0 ];
496- msghdr .msg_iovlen = 2 ;
497- msg_iov [0 ].iov_base = relay_frame ;
498- msg_iov [0 ].iov_len = 38 ;
499- msg_iov [1 ].iov_len = msg_len ;
500515 tr_debug ("Forward Client msg to server" );
501516 tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT ;
502517
503518 }
504519 socket_setsockopt (sckt_data -> socket_id , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_TCLASS , & tc , sizeof (tc ));
505520 socket_sendmsg (sckt_data -> socket_id , & msghdr , NS_MSG_LEGACY0 );
506521cleanup :
507- ns_dyn_mem_free (msg_iov [ 1 ]. iov_base );
522+ ns_dyn_mem_free (socket_data );
508523
509524 return ;
510525}
@@ -635,6 +650,7 @@ uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_ty
635650 relay_srv -> instance_id = id ;
636651 relay_srv -> interface_id = interface_id ;
637652 relay_srv -> relay_activated = false;
653+ relay_srv -> add_interface_id_option = false;
638654
639655 }
640656
@@ -655,6 +671,14 @@ void dhcp_service_relay_instance_enable(uint16_t instance, uint8_t *server_addre
655671 }
656672}
657673
674+ void dhcp_service_relay_interface_id_option_enable (uint16_t instance , bool enable )
675+ {
676+ relay_instance_t * relay_srv = dhcp_service_relay_find (instance );
677+ if (relay_srv ) {
678+ relay_srv -> add_interface_id_option = enable ;
679+ }
680+ }
681+
658682uint8_t * dhcp_service_relay_global_addres_get (uint16_t instance )
659683{
660684 relay_instance_t * relay_srv = dhcp_service_relay_find (instance );
@@ -851,30 +875,42 @@ void dhcp_service_send_message(msg_tr_t *msg_tr_ptr)
851875 //Build Relay Reply only server do this
852876 int16_t tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT ;
853877 socket_setsockopt (msg_tr_ptr -> socket , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_TCLASS , & tc , sizeof (tc ));
854- ns_iovec_t data_vector [2 ];
878+ ns_iovec_t data_vector [4 ];
879+ uint8_t relay_header [4 ];
880+ libdhcpv6_dhcp_option_header_write (relay_header , DHCPV6_OPTION_RELAY , msg_tr_ptr -> msg_len );
855881 ns_msghdr_t msghdr ;
882+ msghdr .msg_iovlen = 0 ;
856883 memcpy (msg_tr_ptr -> addr .address , msg_tr_ptr -> relay_start + 2 , 16 );
857884 msg_tr_ptr -> addr .identifier = DHCPV6_SERVER_PORT ;
858885 //SET IOV vectors
859886 //Relay Reply
860- data_vector [0 ].iov_base = (void * ) msg_tr_ptr -> relay_start ;
861- data_vector [0 ].iov_len = DHCPV6_RELAY_LENGTH + 4 ;
887+ data_vector [msghdr .msg_iovlen ].iov_base = (void * ) msg_tr_ptr -> relay_start ;
888+ data_vector [msghdr .msg_iovlen ].iov_len = DHCPV6_RELAY_LENGTH ;
889+ msghdr .msg_iovlen ++ ;
890+ if (msg_tr_ptr -> opt_interface_id ) {
891+ data_vector [msghdr .msg_iovlen ].iov_base = (void * )(msg_tr_ptr -> opt_interface_id - 4 );
892+ data_vector [msghdr .msg_iovlen ].iov_len = msg_tr_ptr -> opt_interface_id_length + 4 ;
893+ msghdr .msg_iovlen ++ ;
894+ }
895+ //Relay reply header
896+ data_vector [msghdr .msg_iovlen ].iov_base = (void * ) relay_header ;
897+ data_vector [msghdr .msg_iovlen ].iov_len = 4 ;
898+ msghdr .msg_iovlen ++ ;
862899 //DHCPV normal message vector
863- data_vector [1 ].iov_base = (void * ) msg_tr_ptr -> msg_ptr ;
864- data_vector [1 ].iov_len = msg_tr_ptr -> msg_len ;
900+ data_vector [msghdr .msg_iovlen ].iov_base = (void * ) msg_tr_ptr -> msg_ptr ;
901+ data_vector [msghdr .msg_iovlen ].iov_len = msg_tr_ptr -> msg_len ;
902+ msghdr .msg_iovlen ++ ;
865903
866904 //Set message name
867905 msghdr .msg_name = (void * ) & msg_tr_ptr -> addr ;
868906 msghdr .msg_namelen = sizeof (ns_address_t );
869907 msghdr .msg_iov = & data_vector [0 ];
870- msghdr .msg_iovlen = 2 ;
871908 //No ancillary data
872909 msghdr .msg_control = NULL ;
873910 msghdr .msg_controllen = 0 ;
874911
875912 uint8_t * ptr = msg_tr_ptr -> relay_start ;
876913 * ptr = DHCPV6_RELAY_REPLY ;
877- libdhcpv6_dhcp_option_header_write (ptr + 34 , msg_tr_ptr -> msg_len );
878914 retval = socket_sendmsg (msg_tr_ptr -> socket , & msghdr , NS_MSG_LEGACY0 );
879915
880916 } else {
@@ -972,6 +1008,12 @@ void dhcp_service_relay_instance_enable(uint16_t instance, uint8_t *server_addre
9721008 (void )server_address ;
9731009}
9741010
1011+ void dhcp_service_relay_interface_id_option_enable (uint16_t instance , bool enable )
1012+ {
1013+ (void )instance ;
1014+ (void )enable ;
1015+ }
1016+
9751017int dhcp_service_send_resp (uint32_t msg_tr_id , uint8_t options , uint8_t * msg_ptr , uint16_t msg_len )
9761018{
9771019 (void )msg_tr_id ;
0 commit comments