Compare commits
	
		
			11 Commits
		
	
	
		
			3ecbb0199e
			...
			main
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 3db02d166c | ||
|  | 6f5cde1aff | ||
|  | 61386a1c63 | ||
|  | 25b2999485 | ||
|  | cb78074e46 | ||
|  | 0d864a71fe | ||
|  | e19f45e29c | ||
|  | a960d64a87 | ||
|  | c8dc522fe9 | ||
|  | 4b9c556f08 | ||
|  | 7e482adb4f | 
							
								
								
									
										26
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								README.md
									
									
									
									
									
								
							| @@ -13,28 +13,30 @@ See previous work: | |||||||
| *   [netlink listener](https://gerrit.fd.io/r/c/vpp/+/31122) | *   [netlink listener](https://gerrit.fd.io/r/c/vpp/+/31122) | ||||||
|  |  | ||||||
| My work is intended to be re-submitted for review as a cleanup/rewrite of the | My work is intended to be re-submitted for review as a cleanup/rewrite of the | ||||||
| existing Linux CP interface mirror and netlink syncer.  | existing Linux CP interface mirror and netlink syncer. I will use this repo | ||||||
|  | to make rapid prototyping progress, sometimes with other software engineers. | ||||||
|  |  | ||||||
| Follow along on [my blog](https://ipng.ch/s/articles/) for my findings while | Follow along on [my blog](https://ipng.ch/s/articles/) for my findings while | ||||||
| I work towards a completed plugin that can copy VPP configuration into Linux | I work towards feature completion. When the code is complete, this plugin should | ||||||
| interfaces, and copy Linux configuration changes into VPP (ie. a fully | be able to work seamlessly with a higher level controlplane like [FRR](https://frrouting.org/) | ||||||
| bidirectional pipe between Linux and VPP). | or [Bird](https://bird.network.cz/), for example as a BGP/OSPF speaking ISP router. | ||||||
|  |  | ||||||
| When the code is complete, this plugin should be able to work seamlessly with |  | ||||||
| a higher level controlplane like [FRR](https://frrouting.org/) or |  | ||||||
| [Bird](https://bird.network.cz/), for example as a BGP/OSPF speaking ISP router. |  | ||||||
|  |  | ||||||
| ## WARNING!! | ## WARNING!! | ||||||
|  |  | ||||||
| The only reason that this code is here, is so that I can make some progress | Users should use the `linux-cp` plugin that natively ships with VPP since 2022. | ||||||
|  |  | ||||||
|  | The only reason that this code is still here, is so that I can make some progress | ||||||
| iterating on the Linux CP plugin, and share my findings with some interested | iterating on the Linux CP plugin, and share my findings with some interested | ||||||
| folks. The goal is NOT to use this plugin anywhere other than a bench. I | folks. The goal is NOT to use this plugin anywhere other than a bench. I | ||||||
| intend to contribute the plugin back upstream as soon as it's peer reviewed! | intend to contribute any changes submitted to this copy of the plugin back | ||||||
|  | upstream as soon as they have had some mileage and peer review! | ||||||
|  |  | ||||||
| ***Pull Requests and Issues will be immediately closed without warning*** | ***Pull Requests and Issues will be immediately closed without warning*** | ||||||
|  |  | ||||||
| VPP's code lives at [fd.io](https://gerrit.fd.io/r/c/vpp), and this copy is | VPP's code lives at [fd.io](https://gerrit.fd.io/r/c/vpp), and this copy is | ||||||
| shared only for convenience purposes. | shared only for convenience purposes. If you do require support, you can  | ||||||
|  | discuss your case on the VPP Developer mailinglist at vpp-dev@lists.fd.io | ||||||
|  | or alternatively you can ask for a commercial support quote at sales@ipng.ch. | ||||||
|  |  | ||||||
| ## Functionality | ## Functionality | ||||||
|  |  | ||||||
| @@ -158,7 +160,7 @@ wget http://deb.debian.org/debian/pool/main/libn/libnl3/libnl3_3.7.0-0.2.debian. | |||||||
|  |  | ||||||
| tar xzf libnl3_3.7.0.orig.tar.gz | tar xzf libnl3_3.7.0.orig.tar.gz | ||||||
| cd libnl-3.7.0 | cd libnl-3.7.0 | ||||||
| tar xf libnl3_3.7.0-0.2.debian.tar.xz | tar xf ../libnl3_3.7.0-0.2.debian.tar.xz | ||||||
|  |  | ||||||
| sudo apt install dpkg-dev debhelper dh-exec cdbs bison flex automake autoconf \ | sudo apt install dpkg-dev debhelper dh-exec cdbs bison flex automake autoconf \ | ||||||
|   dh-autoreconf pkg-config |   dh-autoreconf pkg-config | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								lcpng.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								lcpng.c
									
									
									
									
									
								
							| @@ -95,6 +95,26 @@ lcp_sync (void) | |||||||
|   return lcpm->lcp_sync; |   return lcpm->lcp_sync; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | lcp_set_sync_unnumbered (u8 is_sync) | ||||||
|  | { | ||||||
|  |   lcp_main_t *lcpm = &lcp_main; | ||||||
|  |  | ||||||
|  |   lcpm->lcp_sync_unnumbered = (is_sync != 0); | ||||||
|  |  | ||||||
|  |   // If we set to 'on', do a one-off sync of LCP interfaces | ||||||
|  |   if (is_sync) | ||||||
|  |     lcp_itf_pair_sync_state_all (); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int | ||||||
|  | lcp_sync_unnumbered (void) | ||||||
|  | { | ||||||
|  |   lcp_main_t *lcpm = &lcp_main; | ||||||
|  |  | ||||||
|  |   return lcpm->lcp_sync_unnumbered; | ||||||
|  | } | ||||||
|  |  | ||||||
| void | void | ||||||
| lcp_set_auto_subint (u8 is_auto) | lcp_set_auto_subint (u8 is_auto) | ||||||
| { | { | ||||||
| @@ -111,6 +131,28 @@ lcp_auto_subint (void) | |||||||
|   return lcpm->lcp_auto_subint; |   return lcpm->lcp_auto_subint; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | lcp_set_default_num_queues (u16 num_queues, u8 is_tx) | ||||||
|  | { | ||||||
|  |   lcp_main_t *lcpm = &lcp_main; | ||||||
|  |  | ||||||
|  |   if (is_tx) | ||||||
|  |     lcpm->num_tx_queues = num_queues; | ||||||
|  |   else | ||||||
|  |     lcpm->num_rx_queues = num_queues; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | u16 | ||||||
|  | lcp_get_default_num_queues (u8 is_tx) | ||||||
|  | { | ||||||
|  |   lcp_main_t *lcpm = &lcp_main; | ||||||
|  |  | ||||||
|  |   if (is_tx) | ||||||
|  |     return lcpm->num_tx_queues; | ||||||
|  |  | ||||||
|  |   return lcpm->num_rx_queues ?: vlib_num_workers (); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * fd.io coding-style-patch-verification: ON |  * fd.io coding-style-patch-verification: ON | ||||||
|  * |  * | ||||||
|   | |||||||
							
								
								
									
										11
									
								
								lcpng.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								lcpng.h
									
									
									
									
									
								
							| @@ -26,6 +26,9 @@ typedef struct lcp_main_s | |||||||
|   int default_ns_fd; |   int default_ns_fd; | ||||||
|   u8 lcp_auto_subint; /* Automatically create/delete LCP sub-interfaces */ |   u8 lcp_auto_subint; /* Automatically create/delete LCP sub-interfaces */ | ||||||
|   u8 lcp_sync;	      /* Automatically sync VPP changes to LCP */ |   u8 lcp_sync;	      /* Automatically sync VPP changes to LCP */ | ||||||
|  |   u8 lcp_sync_unnumbered; /* Automatically sync unnumbered interfaces to LCP */ | ||||||
|  |   u16 num_rx_queues; | ||||||
|  |   u16 num_tx_queues; | ||||||
|   /* Set when Unit testing */ |   /* Set when Unit testing */ | ||||||
|   u8 test_mode; |   u8 test_mode; | ||||||
| } lcp_main_t; | } lcp_main_t; | ||||||
| @@ -39,11 +42,17 @@ int lcp_set_default_ns (u8 *ns); | |||||||
| u8 *lcp_get_default_ns (void); /* Returns NULL or shared string */ | u8 *lcp_get_default_ns (void); /* Returns NULL or shared string */ | ||||||
| int lcp_get_default_ns_fd (void); | int lcp_get_default_ns_fd (void); | ||||||
|  |  | ||||||
| /* | /** | ||||||
|  * Sync state from VPP into all LCP devices |  * Sync state from VPP into all LCP devices | ||||||
|  */ |  */ | ||||||
| void lcp_itf_pair_sync_state_all (); | void lcp_itf_pair_sync_state_all (); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Get/Set the default queue number for LCP host taps. | ||||||
|  |  */ | ||||||
|  | void lcp_set_default_num_queues (u16 num_queues, u8 is_tx); | ||||||
|  | u16 lcp_get_default_num_queues (u8 is_tx); | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| /* | /* | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								lcpng_if.api
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lcpng_if.api
									
									
									
									
									
								
							| @@ -101,13 +101,28 @@ define lcp_itf_pair_add_del_v2_reply | |||||||
|     @param context - sender context, to match reply w/ request |     @param context - sender context, to match reply w/ request | ||||||
|     @param sw_if_index - interface to use as filter (~0 == "all") |     @param sw_if_index - interface to use as filter (~0 == "all") | ||||||
| */ | */ | ||||||
| define lcp_itf_pair_get | autoendian define lcp_itf_pair_get | ||||||
| { | { | ||||||
|   u32 client_index; |   u32 client_index; | ||||||
|   u32 context; |   u32 context; | ||||||
|   u32 cursor; |   u32 cursor; | ||||||
| }; | }; | ||||||
| define lcp_itf_pair_get_reply | autoendian define lcp_itf_pair_get_reply | ||||||
|  | { | ||||||
|  |   u32 context; | ||||||
|  |   i32 retval; | ||||||
|  |   u32 cursor; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | autoendian define lcp_itf_pair_get_v2 | ||||||
|  | { | ||||||
|  |   u32 client_index; | ||||||
|  |   u32 context; | ||||||
|  |   u32 cursor; | ||||||
|  |   vl_api_interface_index_t sw_if_index [default=0xffffffff]; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | autoendian define lcp_itf_pair_get_v2_reply | ||||||
| { | { | ||||||
|   u32 context; |   u32 context; | ||||||
|   i32 retval; |   i32 retval; | ||||||
|   | |||||||
| @@ -133,11 +133,11 @@ send_lcp_itf_pair_details (index_t lipi, vl_api_registration_t *rp, | |||||||
|   vl_api_lcp_itf_pair_details_t *rmp; |   vl_api_lcp_itf_pair_details_t *rmp; | ||||||
|   lcp_itf_pair_t *lcp_pair = lcp_itf_pair_get (lipi); |   lcp_itf_pair_t *lcp_pair = lcp_itf_pair_get (lipi); | ||||||
|  |  | ||||||
|   REPLY_MACRO_DETAILS4 ( |   REPLY_MACRO_DETAILS4_END ( | ||||||
|     VL_API_LCP_ITF_PAIR_DETAILS, rp, context, ({ |     VL_API_LCP_ITF_PAIR_DETAILS, rp, context, ({ | ||||||
|       rmp->phy_sw_if_index = ntohl (lcp_pair->lip_phy_sw_if_index); |       rmp->phy_sw_if_index = lcp_pair->lip_phy_sw_if_index; | ||||||
|       rmp->host_sw_if_index = ntohl (lcp_pair->lip_host_sw_if_index); |       rmp->host_sw_if_index = lcp_pair->lip_host_sw_if_index; | ||||||
|       rmp->vif_index = ntohl (lcp_pair->lip_vif_index); |       rmp->vif_index = lcp_pair->lip_vif_index; | ||||||
|       rmp->host_if_type = api_encode_host_type (lcp_pair->lip_host_type); |       rmp->host_if_type = api_encode_host_type (lcp_pair->lip_host_type); | ||||||
|  |  | ||||||
|       memcpy_s (rmp->host_if_name, sizeof (rmp->host_if_name), |       memcpy_s (rmp->host_if_name, sizeof (rmp->host_if_name), | ||||||
| @@ -156,11 +156,44 @@ vl_api_lcp_itf_pair_get_t_handler (vl_api_lcp_itf_pair_get_t *mp) | |||||||
|   vl_api_lcp_itf_pair_get_reply_t *rmp; |   vl_api_lcp_itf_pair_get_reply_t *rmp; | ||||||
|   i32 rv = 0; |   i32 rv = 0; | ||||||
|  |  | ||||||
|   REPLY_AND_DETAILS_MACRO ( |   REPLY_AND_DETAILS_MACRO_END ( | ||||||
|     VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool, |     VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool, | ||||||
|     ({ send_lcp_itf_pair_details (cursor, rp, mp->context); })); |     ({ send_lcp_itf_pair_details (cursor, rp, mp->context); })); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | vl_api_lcp_itf_pair_get_v2_t_handler (vl_api_lcp_itf_pair_get_v2_t *mp) | ||||||
|  | { | ||||||
|  |   vl_api_lcp_itf_pair_get_v2_reply_t *rmp; | ||||||
|  |   i32 rv = 0; | ||||||
|  |  | ||||||
|  |   if (mp->sw_if_index == ~0) | ||||||
|  |     { | ||||||
|  |       // Does this actually work? | ||||||
|  |       REPLY_AND_DETAILS_MACRO_END ( | ||||||
|  | 	VL_API_LCP_ITF_PAIR_GET_REPLY, lcp_itf_pair_pool, | ||||||
|  | 	({ send_lcp_itf_pair_details (cursor, rp, mp->context); })); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       VALIDATE_SW_IF_INDEX_END (mp); | ||||||
|  |  | ||||||
|  |       u32 pair_index = lcp_itf_pair_find_by_phy (mp->sw_if_index); | ||||||
|  |       if (pair_index == INDEX_INVALID) | ||||||
|  | 	{ | ||||||
|  | 	  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; | ||||||
|  | 	  goto bad_sw_if_index; | ||||||
|  | 	} | ||||||
|  |       send_lcp_itf_pair_details ( | ||||||
|  | 	pair_index, vl_api_client_index_to_registration (mp->client_index), | ||||||
|  | 	mp->context); | ||||||
|  |  | ||||||
|  |       BAD_SW_IF_INDEX_LABEL; | ||||||
|  |       REPLY_MACRO2_END (VL_API_LCP_ITF_PAIR_GET_V2_REPLY, | ||||||
|  | 			({ rmp->cursor = ~0; })); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp) | vl_api_lcp_default_ns_set_t_handler (vl_api_lcp_default_ns_set_t *mp) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -142,6 +142,37 @@ VLIB_CLI_COMMAND (lcp_sync_command, static) = { | |||||||
|   .function = lcp_sync_command_fn, |   .function = lcp_sync_command_fn, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | static clib_error_t * | ||||||
|  | lcp_sync_unnumbered_command_fn (vlib_main_t *vm, unformat_input_t *input, | ||||||
|  | 				vlib_cli_command_t *cmd) | ||||||
|  | { | ||||||
|  |   unformat_input_t _line_input, *line_input = &_line_input; | ||||||
|  |  | ||||||
|  |   if (!unformat_user (input, unformat_line_input, line_input)) | ||||||
|  |     return 0; | ||||||
|  |  | ||||||
|  |   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) | ||||||
|  |     { | ||||||
|  |       if (unformat (line_input, "on") || unformat (line_input, "enable")) | ||||||
|  | 	lcp_set_sync_unnumbered (1); | ||||||
|  |       else if (unformat (line_input, "off") || | ||||||
|  | 	       unformat (line_input, "disable")) | ||||||
|  | 	lcp_set_sync_unnumbered (0); | ||||||
|  |       else | ||||||
|  | 	return clib_error_return (0, "unknown input `%U'", | ||||||
|  | 				  format_unformat_error, line_input); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   unformat_free (line_input); | ||||||
|  |   return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | VLIB_CLI_COMMAND (lcp_sync_unnumbered_command, static) = { | ||||||
|  |   .path = "lcp lcp-sync-unnumbered", | ||||||
|  |   .short_help = "lcp lcp-sync-unnumbered [on|enable|off|disable]", | ||||||
|  |   .function = lcp_sync_unnumbered_command_fn, | ||||||
|  | }; | ||||||
|  |  | ||||||
| static clib_error_t * | static clib_error_t * | ||||||
| lcp_auto_subint_command_fn (vlib_main_t *vm, unformat_input_t *input, | lcp_auto_subint_command_fn (vlib_main_t *vm, unformat_input_t *input, | ||||||
| 			    vlib_cli_command_t *cmd) | 			    vlib_cli_command_t *cmd) | ||||||
|   | |||||||
| @@ -109,7 +109,22 @@ lcp_itf_pair_sync_state (lcp_itf_pair_t *lip) | |||||||
|   /* Linux will remove IPv6 addresses on children when the parent state |   /* Linux will remove IPv6 addresses on children when the parent state | ||||||
|    * goes down, so we ensure all IPv4/IPv6 addresses are synced. |    * goes down, so we ensure all IPv4/IPv6 addresses are synced. | ||||||
|    */ |    */ | ||||||
|   lcp_itf_set_interface_addr (lip); |   if (sw->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED) | ||||||
|  |     { | ||||||
|  |       if (lcp_sync_unnumbered ()) | ||||||
|  | 	{ | ||||||
|  | 	  lcp_itf_set_interface_addr (lip); | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	{ | ||||||
|  | 	  LCP_IF_NOTICE ("sync_state: not syncing addresses on unnumbered %U", | ||||||
|  | 			 format_lcp_itf_pair, lip); | ||||||
|  | 	} | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       lcp_itf_set_interface_addr (lip); | ||||||
|  |     } | ||||||
|  |  | ||||||
|   if (vif_ns_fd != -1) |   if (vif_ns_fd != -1) | ||||||
|     close (vif_ns_fd); |     close (vif_ns_fd); | ||||||
|   | |||||||
| @@ -133,6 +133,8 @@ lcp_itf_pair_show (u32 phy_sw_if_index) | |||||||
|   vlib_cli_output (vm, "lcp lcp-auto-subint %s\n", |   vlib_cli_output (vm, "lcp lcp-auto-subint %s\n", | ||||||
| 		   lcp_auto_subint () ? "on" : "off"); | 		   lcp_auto_subint () ? "on" : "off"); | ||||||
|   vlib_cli_output (vm, "lcp lcp-sync %s\n", lcp_sync () ? "on" : "off"); |   vlib_cli_output (vm, "lcp lcp-sync %s\n", lcp_sync () ? "on" : "off"); | ||||||
|  |   vlib_cli_output (vm, "lcp lcp-sync-unnumbered %s\n", | ||||||
|  | 		   lcp_sync_unnumbered () ? "on" : "off"); | ||||||
|  |  | ||||||
|   if (phy_sw_if_index == ~0) |   if (phy_sw_if_index == ~0) | ||||||
|     { |     { | ||||||
| @@ -261,7 +263,10 @@ lcp_itf_pair_add (u32 host_sw_if_index, u32 phy_sw_if_index, u8 *host_name, | |||||||
|   vec_validate_init_empty (lip_db_by_host, host_sw_if_index, INDEX_INVALID); |   vec_validate_init_empty (lip_db_by_host, host_sw_if_index, INDEX_INVALID); | ||||||
|   lip_db_by_phy[phy_sw_if_index] = lipi; |   lip_db_by_phy[phy_sw_if_index] = lipi; | ||||||
|   lip_db_by_host[host_sw_if_index] = lipi; |   lip_db_by_host[host_sw_if_index] = lipi; | ||||||
|   hash_set (lip_db_by_vif, host_index, lipi); |   if (clib_strcmp ((char *) ns, (char *) lcp_get_default_ns ()) == 0) | ||||||
|  |     { | ||||||
|  |       hash_set (lip_db_by_vif, host_index, lipi); | ||||||
|  |     } | ||||||
|  |  | ||||||
|   lip->lip_host_sw_if_index = host_sw_if_index; |   lip->lip_host_sw_if_index = host_sw_if_index; | ||||||
|   lip->lip_phy_sw_if_index = phy_sw_if_index; |   lip->lip_phy_sw_if_index = phy_sw_if_index; | ||||||
| @@ -550,6 +555,7 @@ static clib_error_t * | |||||||
| lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input) | lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input) | ||||||
| { | { | ||||||
|   u8 *default_ns; |   u8 *default_ns; | ||||||
|  |   u32 tmp; | ||||||
|  |  | ||||||
|   default_ns = NULL; |   default_ns = NULL; | ||||||
|  |  | ||||||
| @@ -569,6 +575,10 @@ lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input) | |||||||
| 	lcp_set_auto_subint (1 /* is_auto */); | 	lcp_set_auto_subint (1 /* is_auto */); | ||||||
|       else if (unformat (input, "lcp-sync")) |       else if (unformat (input, "lcp-sync")) | ||||||
| 	lcp_set_sync (1 /* is_auto */); | 	lcp_set_sync (1 /* is_auto */); | ||||||
|  |       else if (unformat (input, "num-rx-queues %d", &tmp)) | ||||||
|  | 	lcp_set_default_num_queues (tmp, 0 /* is_tx */); | ||||||
|  |       else if (unformat (input, "num-tx-queues %d", &tmp)) | ||||||
|  | 	lcp_set_default_num_queues (tmp, 1 /* is_tx */); | ||||||
|       else |       else | ||||||
| 	return clib_error_return (0, "unknown input `%U'", | 	return clib_error_return (0, "unknown input `%U'", | ||||||
| 				  format_unformat_error, input); | 				  format_unformat_error, input); | ||||||
| @@ -782,6 +792,14 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, | |||||||
|   const vnet_sw_interface_t *sw; |   const vnet_sw_interface_t *sw; | ||||||
|   const vnet_hw_interface_t *hw; |   const vnet_hw_interface_t *hw; | ||||||
|   lcp_itf_pair_t *lip; |   lcp_itf_pair_t *lip; | ||||||
|  |   index_t lipi; | ||||||
|  |  | ||||||
|  |   lipi = lcp_itf_pair_find_by_phy (phy_sw_if_index); | ||||||
|  |   if (lipi != INDEX_INVALID) | ||||||
|  |     { | ||||||
|  |       LCP_IF_ERROR ("pair_create: already created"); | ||||||
|  |       return VNET_API_ERROR_VALUE_EXIST; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   if (!vnet_sw_if_index_is_api_valid (phy_sw_if_index)) |   if (!vnet_sw_if_index_is_api_valid (phy_sw_if_index)) | ||||||
|     { |     { | ||||||
| @@ -983,8 +1001,10 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, | |||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       tap_create_if_args_t args = { |       tap_create_if_args_t args = { | ||||||
| 	.num_rx_queues = clib_max (1, vlib_num_workers ()), | 	.num_rx_queues = | ||||||
| 	.num_tx_queues = 1, | 	  clib_max (1, lcp_get_default_num_queues (0 /* is_tx */)), | ||||||
|  | 	.num_tx_queues = | ||||||
|  | 	  clib_max (1, lcp_get_default_num_queues (1 /* is_tx */)), | ||||||
| 	.id = ~0, | 	.id = ~0, | ||||||
| 	.sw_if_index = ~0, | 	.sw_if_index = ~0, | ||||||
| 	.rx_ring_sz = 256, | 	.rx_ring_sz = 256, | ||||||
| @@ -1078,7 +1098,7 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, | |||||||
|   vnet_sw_interface_admin_up (vnm, host_sw_if_index); |   vnet_sw_interface_admin_up (vnm, host_sw_if_index); | ||||||
|   if (lcp_sync ()) |   if (lcp_sync ()) | ||||||
|     { |     { | ||||||
|       lip = lcp_itf_pair_get (lcp_itf_pair_find_by_vif (vif_index)); |       lip = lcp_itf_pair_get (lcp_itf_pair_find_by_phy (phy_sw_if_index)); | ||||||
|       lcp_itf_pair_sync_state (lip); |       lcp_itf_pair_sync_state (lip); | ||||||
|     } |     } | ||||||
|   /* |   /* | ||||||
| @@ -1225,6 +1245,8 @@ lcp_itf_pair_init (vlib_main_t *vm) | |||||||
|   tcp_punt_unknown (vm, 0, 1); |   tcp_punt_unknown (vm, 0, 1); | ||||||
|   tcp_punt_unknown (vm, 1, 1); |   tcp_punt_unknown (vm, 1, 1); | ||||||
|  |  | ||||||
|  |   lcp_main.lcp_sync_unnumbered = 1; | ||||||
|  |  | ||||||
|   return NULL; |   return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -166,6 +166,12 @@ int lcp_auto_subint (void); | |||||||
| void lcp_set_sync (u8 is_auto); | void lcp_set_sync (u8 is_auto); | ||||||
| int lcp_sync (void); | int lcp_sync (void); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * sync address of unnumbered interfaces from VPP into LCP | ||||||
|  |  */ | ||||||
|  | void lcp_set_sync_unnumbered (u8 is_sync); | ||||||
|  | int lcp_sync_unnumbered (void); | ||||||
|  |  | ||||||
| typedef void (*lcp_itf_pair_add_cb_t) (lcp_itf_pair_t *); | typedef void (*lcp_itf_pair_add_cb_t) (lcp_itf_pair_t *); | ||||||
| typedef void (*lcp_itf_pair_del_cb_t) (lcp_itf_pair_t *); | typedef void (*lcp_itf_pair_del_cb_t) (lcp_itf_pair_t *); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ | |||||||
| #include <netlink/route/addr.h> | #include <netlink/route/addr.h> | ||||||
|  |  | ||||||
| #include <vlib/vlib.h> | #include <vlib/vlib.h> | ||||||
|  | #include <vlib/file.h> | ||||||
| #include <vlib/unix/unix.h> | #include <vlib/unix/unix.h> | ||||||
| #include <vppinfra/error.h> | #include <vppinfra/error.h> | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1149,7 +1149,7 @@ lcp_nl_neigh_add (struct rtnl_neigh *rn) | |||||||
|  |  | ||||||
|   if ((rna = rtnl_neigh_get_dst (rn)) == NULL) |   if ((rna = rtnl_neigh_get_dst (rn)) == NULL) | ||||||
|     { |     { | ||||||
|       LCP_NL_DBG ("neigh_del: ignore missing neighbor %U", format_nl_object, |       LCP_NL_DBG ("neigh_add: ignore missing neighbor %U", format_nl_object, | ||||||
| 		  rn); | 		  rn); | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user