@@ -60,6 +60,7 @@ typedef struct {
60
60
int8_t interface_id ;
61
61
uint8_t server_address [16 ];
62
62
bool relay_activated ;
63
+ bool add_interface_id_option ;
63
64
ns_list_link_t link ;
64
65
} relay_instance_t ;
65
66
typedef NS_LIST_HEAD (relay_instance_t , link ) relay_instance_list_t ;
@@ -83,6 +84,8 @@ typedef struct {
83
84
uint8_t * msg_ptr ;
84
85
uint16_t msg_len ;
85
86
uint8_t * relay_start ;
87
+ uint8_t * opt_interface_id ;
88
+ uint16_t opt_interface_id_length ;
86
89
ns_list_link_t link ;
87
90
} msg_tr_t ;
88
91
typedef NS_LIST_HEAD (msg_tr_t , link ) tr_list_t ;
@@ -335,6 +338,8 @@ void recv_dhcp_server_msg(void *cb_res)
335
338
}
336
339
//Update Source and data
337
340
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 ;
338
343
memcpy (msg_tr_ptr -> addr .address , relay_msg .peer_address , 16 );
339
344
msg_ptr = relay_msg .relay_options .msg_ptr ;
340
345
msg_len = relay_msg .relay_options .len ;
@@ -408,35 +413,37 @@ void recv_dhcp_relay_msg(void *cb_res)
408
413
}
409
414
ns_address_t src_address ;
410
415
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 ) {
418
423
// read actual message
419
424
tr_error ("Out of resources" );
420
425
goto cleanup ;
421
426
}
422
427
428
+
423
429
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 ;
424
433
//Set messages name buffer
425
434
msghdr .msg_name = & src_address ;
426
435
msghdr .msg_namelen = sizeof (src_address );
427
- msghdr .msg_iov = & msg_iov [ 1 ] ;
436
+ msghdr .msg_iov = & msg_data ;
428
437
msghdr .msg_iovlen = 1 ;
429
438
msghdr .msg_control = NULL ;
430
439
msghdr .msg_controllen = 0 ;
431
440
432
441
msg_len = socket_recvmsg (sckt_data -> socket_id , & msghdr , NS_MSG_LEGACY0 );
433
442
434
-
435
443
tr_debug ("dhcp Relay recv msg" );
436
444
437
445
//Parse type
438
- uint8_t * ptr = msg_iov [1 ].iov_base ;
439
- uint8_t msg_type = * ptr ;
446
+ uint8_t msg_type = * socket_data ;
440
447
441
448
int16_t tc = 0 ;
442
449
if (msg_type == DHCPV6_RELAY_FORWARD ) {
@@ -446,7 +453,7 @@ void recv_dhcp_relay_msg(void *cb_res)
446
453
} else if (msg_type == DHCPV6_RELAY_REPLY ) {
447
454
//Parse and validate Relay
448
455
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 )) {
450
457
tr_error ("Not valid relay" );
451
458
goto cleanup ;
452
459
}
@@ -458,14 +465,14 @@ void recv_dhcp_relay_msg(void *cb_res)
458
465
memcpy (src_address .address , relay_msg .peer_address , 16 );
459
466
src_address .type = ADDRESS_IPV6 ;
460
467
src_address .identifier = DHCPV6_CLIENT_PORT ;
461
- msghdr .msg_iov = & msg_iov [ 0 ] ;
468
+ msghdr .msg_iov = & msg_data ;
462
469
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 ;
465
472
tr_debug ("Forward Original relay msg to client" );
466
473
467
474
} else {
468
- if (0 != libdhcpv6_message_malformed_check (ptr , msg_len )) {
475
+ if (0 != libdhcpv6_message_malformed_check (socket_data , msg_len )) {
469
476
tr_error ("Malformed packet" );
470
477
goto cleanup ;
471
478
}
@@ -476,10 +483,24 @@ void recv_dhcp_relay_msg(void *cb_res)
476
483
tr_error ("No GP address" );
477
484
goto cleanup ;
478
485
}
479
-
486
+ ns_iovec_t msg_iov [2 ];
487
+ uint8_t * ptr = relay_frame ;
480
488
//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 ;
483
504
484
505
//Update Neighbour table if necessary
485
506
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)
491
512
memcpy (src_address .address , relay_srv -> server_address , 16 );
492
513
src_address .type = ADDRESS_IPV6 ;
493
514
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 ;
500
515
tr_debug ("Forward Client msg to server" );
501
516
tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT ;
502
517
503
518
}
504
519
socket_setsockopt (sckt_data -> socket_id , SOCKET_IPPROTO_IPV6 , SOCKET_IPV6_TCLASS , & tc , sizeof (tc ));
505
520
socket_sendmsg (sckt_data -> socket_id , & msghdr , NS_MSG_LEGACY0 );
506
521
cleanup :
507
- ns_dyn_mem_free (msg_iov [ 1 ]. iov_base );
522
+ ns_dyn_mem_free (socket_data );
508
523
509
524
return ;
510
525
}
@@ -635,6 +650,7 @@ uint16_t dhcp_service_init(int8_t interface_id, dhcp_instance_type_e instance_ty
635
650
relay_srv -> instance_id = id ;
636
651
relay_srv -> interface_id = interface_id ;
637
652
relay_srv -> relay_activated = false;
653
+ relay_srv -> add_interface_id_option = false;
638
654
639
655
}
640
656
@@ -655,6 +671,14 @@ void dhcp_service_relay_instance_enable(uint16_t instance, uint8_t *server_addre
655
671
}
656
672
}
657
673
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
+
658
682
uint8_t * dhcp_service_relay_global_addres_get (uint16_t instance )
659
683
{
660
684
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)
851
875
//Build Relay Reply only server do this
852
876
int16_t tc = IP_DSCP_CS6 << IP_TCLASS_DSCP_SHIFT ;
853
877
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 );
855
881
ns_msghdr_t msghdr ;
882
+ msghdr .msg_iovlen = 0 ;
856
883
memcpy (msg_tr_ptr -> addr .address , msg_tr_ptr -> relay_start + 2 , 16 );
857
884
msg_tr_ptr -> addr .identifier = DHCPV6_SERVER_PORT ;
858
885
//SET IOV vectors
859
886
//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 ++ ;
862
899
//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 ++ ;
865
903
866
904
//Set message name
867
905
msghdr .msg_name = (void * ) & msg_tr_ptr -> addr ;
868
906
msghdr .msg_namelen = sizeof (ns_address_t );
869
907
msghdr .msg_iov = & data_vector [0 ];
870
- msghdr .msg_iovlen = 2 ;
871
908
//No ancillary data
872
909
msghdr .msg_control = NULL ;
873
910
msghdr .msg_controllen = 0 ;
874
911
875
912
uint8_t * ptr = msg_tr_ptr -> relay_start ;
876
913
* ptr = DHCPV6_RELAY_REPLY ;
877
- libdhcpv6_dhcp_option_header_write (ptr + 34 , msg_tr_ptr -> msg_len );
878
914
retval = socket_sendmsg (msg_tr_ptr -> socket , & msghdr , NS_MSG_LEGACY0 );
879
915
880
916
} else {
@@ -972,6 +1008,12 @@ void dhcp_service_relay_instance_enable(uint16_t instance, uint8_t *server_addre
972
1008
(void )server_address ;
973
1009
}
974
1010
1011
+ void dhcp_service_relay_interface_id_option_enable (uint16_t instance , bool enable )
1012
+ {
1013
+ (void )instance ;
1014
+ (void )enable ;
1015
+ }
1016
+
975
1017
int dhcp_service_send_resp (uint32_t msg_tr_id , uint8_t options , uint8_t * msg_ptr , uint16_t msg_len )
976
1018
{
977
1019
(void )msg_tr_id ;
0 commit comments