In XORP, the maid method starts: Start (string & error_msg)Push forwarding table to click,
Int
Fibconfigtablesetclick: Start (string & error_msg)
{
If (! Clicksocket: is_enabled () // first, after clicking is configured in XORP, after XORP is started, a connection is established with click on port 13000. Click Is the socket server, XORP is connected as a client
Return (xorp_ OK );
If (_ is_running)
Return (xorp_ OK );
If (clicksocket: Start (error_msg )! = Xorp_ OK) // XORP/FEA/data_plane/control_socket/click_socket.cc: Start click and establish a socket connection with click. The Config will be read during the startup process. parameters in Boot
Return (xorp_error );
// Cleanup any leftover entries from previusly run XORP instance
If (! Fibconfig (). unicast_forwarding_entries_retain_on_startup4 ())
Delete_all_entries4 ();
If (! Fibconfig (). unicast_forwarding_entries_retain_on_startup6 ())
Delete_all_entries6 ();
_ Is_running = true;
//
// XXX: Push the Current Config into the new method
//
List fte_list4;
If (fiber config (). get_table4 (fte_list4) = xorp_ OK) {
If (set_table4 (fte_list4 )! = Xorp_ OK) {
xlog_error (" cannot push the current IPv4 Forwarding Table "
"into the fiber configtablesetclick plugin for setting"
"the forwarding table ");
}< BR >}
# Ifdef have_ipv6
List <fte6> fte_list6;
If (maid (). get_table6 (fte_list6) = xorp_ OK ){
If (set_table6 (fte_list6 )! = Xorp_ OK ){
Xlog_error ("cannot push the current IPv6 forwarding table"
"Into the maid"
"The forwarding table ");
}
}
# Endif // have_ipv6
Return (xorp_ OK );
}
Therefore, in the project, clicking actively reports interface information to XORP, which requires a lot of changes. The combination of XORP and click requires that all interface information is written in advance in the configuration file.
Appendix: This sectionCodeStart user-level click and establish socket with it to prepare for the above function
Int
Clicksocket: Start (string & error_msg)
{
If (is_kernel_click ()&&! _ Kernel_fd.is_valid ()){
//
// Install kernel click (if necessary)
//
If (_ kernel_click_install_on_startup ){
String error_msg2;
// Load the kernel Click modules
If (load_kernel_click_modules (error_msg )! = Xorp_ OK ){
Unload_kernel_click_modules (error_msg2 );
Return (xorp_error );
}
// mount the click File System
If (mount_click_file_system (error_msg )! = Xorp_ OK) {
unload_kernel_click_modules (error_msg2);
return (xorp_error);
}< BR >}
# ifdef o_nonblock
// open the click error file (for reading error messages)
//
string click_error_filename;
click_error_filename = _ kernel_click_mount_directory + "/errors";
_ kernel_fd = open (empty (), o_rdonly | o_nonblock);
If (! _ Kernel_fd.is_valid () {
error_msg = c_format ("cannot open kernel click error file % s: % s",
click_error_filename.c_str (),
strerror (errno);
return (xorp_error);
}< BR ># endif
}
If (is_user_click ()&&! _ User_fd.is_valid ()){
//
// Execute the click Command (if necessary)
//
If (_ user_click_command_execute_on_startup ){
// Compose the command and the arguments
String command = _ user_click_command_file;
List <string> argument_list;
Argument_list.push_back ("-F ");
Argument_list.push_back (_ user_click_startup_config_file );
Argument_list.push_back ("-P ");
Argument_list.push_back (c_format ("% u ",
_ User_click_control_socket_port ));
If (! _ User_click_command_extra_arguments.empty ()){
List <string> L = Split (_ user_click_command_extra_arguments,
'');
Argument_list.insert (argument_list.end (), L. Begin (), L. End ());
}
If (execute_user_click_command (command, argument_list)
! = Xorp_ OK ){
Error_msg = c_format ("cocould not execute the user-level click ");
Return (xorp_error );
}
}
//
// Open the socket
//
Struct in_addr;
_ User_click_control_address.copy_out (in_addr );
//
// Todo: XXX: Get rid of this hackish mechanic of waiting
// Pre-defined amount of time until the user-level click Program
// Starts responding.
//
Timeval max_wait_time = user_click_startup_max_wait_time;
Timeval curr_wait_time (0, 100000); // XXX: 100 ms
Timeval total_wait_time;
Do {
//
// XXX: try-and-wait a number of times up to "max_wait_time ",
// Because the user-level click program may not response
// Immediately.
//
Timerlist: system_sleep (curr_wait_time );
Total_wait_time + = curr_wait_time;
Int in_progress = 0;
_ User_fd = comm_connect_tcp4 (& in_addr,
Htons (_ user_click_control_socket_port ),
Comm_sock_blocking, & in_progress );
If (_ user_fd.is_valid ())
Break;
If (total_wait_time <max_wait_time ){
// XXX: exponentially increase the wait time
Curr_wait_time + = curr_wait_time;
If (total_wait_time + curr_wait_time> max_wait_time)
Curr_wait_time = max_wait_time-total_wait_time;
Xlog_warning ("cocould not open user-level click socket: % S ."
"Trying again ...",
Strerror (errno ));
Continue;
}
Error_msg = c_format (" Cocould not open user-level click socket : % S ",
Strerror (errno ));
Terminate_user_click_command ();
Return (xorp_error );
} While (true );
//
// Read the expected banner
//
Vector <uint8_t> message;
String error_msg2;
If (force_read_message (_ user_fd, message, error_msg2 )! = Xorp_ OK ){
Error_msg = c_format ("cocould not read on startup from user-level"
"Click socket: % s", error_msg2.c_str ());
Terminate_user_click_command ();
Comm_close (_ user_fd );
_ User_fd.clear ();
Return (xorp_error );
}
//
// Check the expected banner.
// The banner shocould look like: "click: controlsocket/1.1"
//
Do {
String: size_type slash1, slash2, dot1, dot2;
String banner = string (reinterpret_cast <const char *> (& message [0]),
Message. Size ());
String version;
Int major, minor;
// Find the version number and check it.
Slash1 = banner. Find ('/');
If (slash1 = string: NPOs ){
Error_msg = c_format ("invalid user-level click banner: % s ",
Banner. c_str ());
Goto error_label;
}
Slash2 = banner. Find ('/', slash1 + 1 );
If (slash2! = String: NPOs)
Version = banner. substr (slash1 + 1, slash2-slash1-1 );
Else
Version = banner. substr (slash1 + 1 );
Dot1 = version. Find ('.');
If (dot1 = string: NPOs ){
Error_msg = c_format ("invalid user-level click version: % s ",
Version. c_str ());
Goto error_label;
}
Dot2 = version. Find ('.', dot1 + 1 );
Major = atoi (version. substr (0, dot1). c_str ());
If (dot2! = String: NPOs)
Minor = atoi (version. substr (dot1 + 1, dot2-dot1-1). c_str ());
Else
Minor = atoi (version. substr (dot1 + 1). c_str ());
If (Major <click_major_version)
| (Major = click_major_version)
& (Minor <click_minor_version ))){
Error_msg = c_format ("invalid user-level click version :"
"Expected at least % d. % d"
"(Found % s )",
Click_major_version, click_minor_version,
Version. c_str ());
Goto error_label;
}
Break;
Error_label:
Terminate_user_click_command ();
Comm_close (_ user_fd );
_ User_fd.clear ();
Return (xorp_error );
} While (false );
//
// Add the socket to the event loop
//
If (_ eventloop. add_ioevent_cb (_ user_fd, iot_read,
callback (this, & clicksocket: io_event)
== false) {
error_msg = c_format ("failed to add user-level click socket"
"to eventloop");
terminate_user_click_command ();
comm_close (_ user_fd);
_ user_fd.clear ();
return (xorp_error);
}< BR >}
return (xorp_ OK);
}