Consolidate MTU and Link changes into one function.
This commit is contained in:
@ -49,6 +49,7 @@ lcp_itf_pair_sync_state (lcp_itf_pair_t *lip)
|
|||||||
int curr_ns_fd = -1;
|
int curr_ns_fd = -1;
|
||||||
int vif_ns_fd = -1;
|
int vif_ns_fd = -1;
|
||||||
u32 mtu;
|
u32 mtu;
|
||||||
|
u32 netlink_mtu;
|
||||||
|
|
||||||
if (!lcp_lcp_sync ())
|
if (!lcp_lcp_sync ())
|
||||||
return;
|
return;
|
||||||
@ -74,9 +75,14 @@ lcp_itf_pair_sync_state (lcp_itf_pair_t *lip)
|
|||||||
lcp_itf_set_link_state (lip, (sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP));
|
lcp_itf_set_link_state (lip, (sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP));
|
||||||
|
|
||||||
/* Linux will clamp MTU of children when the parent is lower. VPP is fine
|
/* Linux will clamp MTU of children when the parent is lower. VPP is fine
|
||||||
* with differing MTUs. Reconcile any differences
|
* with differing MTUs. VPP assumes that if a subint has MTU of 0, that it
|
||||||
|
* inherits from its parent. Linux likes to be more explicit, so we
|
||||||
|
* reconcile any differences.
|
||||||
*/
|
*/
|
||||||
mtu = sw->mtu[VNET_MTU_L3];
|
mtu = sw->mtu[VNET_MTU_L3];
|
||||||
|
if (mtu == 0)
|
||||||
|
mtu = sup_sw->mtu[VNET_MTU_L3];
|
||||||
|
|
||||||
if (sup_sw->mtu[VNET_MTU_L3] < sw->mtu[VNET_MTU_L3])
|
if (sup_sw->mtu[VNET_MTU_L3] < sw->mtu[VNET_MTU_L3])
|
||||||
{
|
{
|
||||||
LCP_ITF_PAIR_WARN ("sync_state: %U flags %u mtu %u sup-mtu %u: "
|
LCP_ITF_PAIR_WARN ("sync_state: %U flags %u mtu %u sup-mtu %u: "
|
||||||
@ -85,8 +91,17 @@ lcp_itf_pair_sync_state (lcp_itf_pair_t *lip)
|
|||||||
sw->mtu[VNET_MTU_L3], sup_sw->mtu[VNET_MTU_L3]);
|
sw->mtu[VNET_MTU_L3], sup_sw->mtu[VNET_MTU_L3]);
|
||||||
mtu = sup_sw->mtu[VNET_MTU_L3];
|
mtu = sup_sw->mtu[VNET_MTU_L3];
|
||||||
}
|
}
|
||||||
vnet_sw_interface_set_mtu (vnet_get_main (), sw->sw_if_index, mtu);
|
|
||||||
vnet_netlink_set_link_mtu (lip->lip_vif_index, mtu);
|
/* Set MTU on all of {sw, tap, netlink}. Only send a netlink message if we
|
||||||
|
* really do want to change the MTU.
|
||||||
|
*/
|
||||||
|
vnet_sw_interface_set_mtu (vnet_get_main (), lip->lip_phy_sw_if_index, mtu);
|
||||||
|
vnet_sw_interface_set_mtu (vnet_get_main (), lip->lip_host_sw_if_index, mtu);
|
||||||
|
if (NULL == vnet_netlink_get_link_mtu (lip->lip_vif_index, &netlink_mtu))
|
||||||
|
{
|
||||||
|
if (netlink_mtu != mtu)
|
||||||
|
vnet_netlink_set_link_mtu (lip->lip_vif_index, mtu);
|
||||||
|
}
|
||||||
|
|
||||||
/* Linux will remove IPv6 addresses on children when the master state
|
/* Linux will remove IPv6 addresses on children when the master state
|
||||||
* goes down, so we ensure all IPv4/IPv6 addresses are synced.
|
* goes down, so we ensure all IPv4/IPv6 addresses are synced.
|
||||||
@ -187,13 +202,9 @@ VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(lcp_itf_admin_state_change);
|
|||||||
static clib_error_t *
|
static clib_error_t *
|
||||||
lcp_itf_mtu_change (vnet_main_t *vnm, u32 sw_if_index, u32 flags)
|
lcp_itf_mtu_change (vnet_main_t *vnm, u32 sw_if_index, u32 flags)
|
||||||
{
|
{
|
||||||
const lcp_itf_pair_t *lip;
|
lcp_itf_pair_t *lip;
|
||||||
vnet_sw_interface_t *sw;
|
|
||||||
int curr_ns_fd = -1;
|
|
||||||
int vif_ns_fd = -1;
|
|
||||||
|
|
||||||
if (!lcp_lcp_sync ())
|
if (!lcp_lcp_sync ())
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
LCP_ITF_PAIR_DBG ("mtu_change: sw %U %u", format_vnet_sw_if_index_name, vnm,
|
LCP_ITF_PAIR_DBG ("mtu_change: sw %U %u", format_vnet_sw_if_index_name, vnm,
|
||||||
sw_if_index, flags);
|
sw_if_index, flags);
|
||||||
@ -203,35 +214,6 @@ lcp_itf_mtu_change (vnet_main_t *vnm, u32 sw_if_index, u32 flags)
|
|||||||
if (!lip)
|
if (!lip)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sw = vnet_get_sw_interface_or_null (vnm, sw_if_index);
|
|
||||||
if (!sw)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (lip->lip_namespace)
|
|
||||||
{
|
|
||||||
curr_ns_fd = clib_netns_open (NULL /* self */);
|
|
||||||
vif_ns_fd = clib_netns_open (lip->lip_namespace);
|
|
||||||
if (vif_ns_fd != -1)
|
|
||||||
clib_setns (vif_ns_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
LCP_ITF_PAIR_INFO ("mtu_change: %U mtu %u", format_lcp_itf_pair, lip,
|
|
||||||
sw->mtu[VNET_MTU_L3]);
|
|
||||||
vnet_netlink_set_link_mtu (lip->lip_vif_index, sw->mtu[VNET_MTU_L3]);
|
|
||||||
if (vif_ns_fd != -1)
|
|
||||||
close (vif_ns_fd);
|
|
||||||
|
|
||||||
if (curr_ns_fd != -1)
|
|
||||||
{
|
|
||||||
clib_setns (curr_ns_fd);
|
|
||||||
close (curr_ns_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When Linux changes MTU on a master interface, all of its children that
|
|
||||||
// have a higher MTU are clamped to this value. This is not true in VPP,
|
|
||||||
// so we are forced to undo that change by walking the sub-interfaces of
|
|
||||||
// a phy and syncing their state back into linux.
|
|
||||||
// For simplicity, just walk all interfaces.
|
|
||||||
lcp_itf_pair_sync_state_all ();
|
lcp_itf_pair_sync_state_all ();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -606,6 +606,7 @@ lcp_validate_if_name (u8 *name)
|
|||||||
void
|
void
|
||||||
lcp_itf_set_link_state (const lcp_itf_pair_t *lip, u8 state)
|
lcp_itf_set_link_state (const lcp_itf_pair_t *lip, u8 state)
|
||||||
{
|
{
|
||||||
|
vnet_main_t *vnm = vnet_get_main ();
|
||||||
int curr_ns_fd, vif_ns_fd;
|
int curr_ns_fd, vif_ns_fd;
|
||||||
|
|
||||||
if (!lip) return;
|
if (!lip) return;
|
||||||
@ -620,6 +621,18 @@ lcp_itf_set_link_state (const lcp_itf_pair_t *lip, u8 state)
|
|||||||
clib_setns (vif_ns_fd);
|
clib_setns (vif_ns_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the same link state on all three (TAP, sw, netlink)
|
||||||
|
*/
|
||||||
|
if (state)
|
||||||
|
{
|
||||||
|
vnet_sw_interface_admin_up (vnm, lip->lip_host_sw_if_index);
|
||||||
|
vnet_sw_interface_admin_up (vnm, lip->lip_phy_sw_if_index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vnet_sw_interface_admin_down (vnm, lip->lip_phy_sw_if_index);
|
||||||
|
vnet_sw_interface_admin_down (vnm, lip->lip_host_sw_if_index);
|
||||||
|
}
|
||||||
vnet_netlink_set_link_state (lip->lip_vif_index, state);
|
vnet_netlink_set_link_state (lip->lip_vif_index, state);
|
||||||
|
|
||||||
if (vif_ns_fd != -1)
|
if (vif_ns_fd != -1)
|
||||||
|
Reference in New Issue
Block a user