platform: workaround for old kernels that don't support IFLA_BR_VLAN_STATS_ENABLED

The kernel of Ubuntu 16.04 doesn't support IFLA_BR_VLAN_STATS_ENABLED.
If we want to run on such old kernels (which we probably do), we need to
detect that, and act accordingly.
This commit is contained in:
Thomas Haller 2020-08-21 13:35:36 +02:00
parent 1407d29b5e
commit 80c0de7217
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
5 changed files with 29 additions and 5 deletions

View file

@ -150,6 +150,8 @@ G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1));
#define IP6_FLOWINFO_TCLASS_SHIFT 20
#define IP6_FLOWINFO_FLOWLABEL_MASK 0x000FFFFF
#define IFLA_BR_VLAN_STATS_ENABLED 41
/*****************************************************************************/
/* Appeared in the kernel prior to 3.13 dated 19 January, 2014 */
@ -1340,6 +1342,13 @@ _parse_lnk_bridge (const char *kind, struct nlattr *info_data)
props = &obj->lnk_bridge;
*props = nm_platform_lnk_bridge_default;
if (!_nm_platform_kernel_support_detected (NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED)) {
/* IFLA_BR_VLAN_STATS_ENABLED was added in kernel 4.10 on April 30, 2016.
* See commit 6dada9b10a0818ba72c249526a742c8c41274a73. */
_nm_platform_kernel_support_init (NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED,
tb[IFLA_BR_VLAN_STATS_ENABLED] ? 1 : -1);
}
if (tb[IFLA_BR_FORWARD_DELAY])
props->forward_delay = nla_get_u32 (tb[IFLA_BR_FORWARD_DELAY]);
if (tb[IFLA_BR_HELLO_TIME])
@ -4065,7 +4074,8 @@ _nl_msg_new_link_set_linkinfo (struct nl_msg *msg,
NLA_PUT_U32 (msg, IFLA_BR_STP_STATE, !!props->stp_state);
NLA_PUT_U16 (msg, IFLA_BR_PRIORITY, props->priority);
NLA_PUT_U16 (msg, IFLA_BR_VLAN_PROTOCOL, htons (props->vlan_protocol));
NLA_PUT_U8 (msg, IFLA_BR_VLAN_STATS_ENABLED, !!props->vlan_stats_enabled);
if (props->vlan_stats_enabled)
NLA_PUT_U8 (msg, IFLA_BR_VLAN_STATS_ENABLED, !!props->vlan_stats_enabled);
NLA_PUT_U16 (msg, IFLA_BR_GROUP_FWD_MASK, props->group_fwd_mask);
NLA_PUT (msg, IFLA_BR_GROUP_ADDR, sizeof (props->group_addr), &props->group_addr);
NLA_PUT_U8 (msg, IFLA_BR_MCAST_SNOOPING, !!props->mcast_snooping);

View file

@ -372,6 +372,11 @@ static const struct {
.name = "FRA_IP_PROTO",
.desc = "FRA_IP_PROTO, FRA_SPORT_RANGE, FRA_DPORT_RANGE attributes for policy routing rules",
},
[NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED] = {
.compile_time_default = (IFLA_BR_MAX >= 41 /* IFLA_BR_VLAN_STATS_ENABLED */),
.name = "IFLA_BR_VLAN_STATS_ENABLE",
.desc = "IFLA_BR_VLAN_STATS_ENABLE bridge link attribute",
},
};
int

View file

@ -967,6 +967,7 @@ typedef enum {
NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_L3MDEV,
NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_UID_RANGE,
NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_PROTOCOL,
NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED,
/* this also includes FRA_SPORT_RANGE and FRA_DPORT_RANGE which
* were added at the same time. */

View file

@ -1983,6 +1983,7 @@ nmtstp_link_set_updown (NMPlatform *platform,
gboolean
nmtstp_kernel_support_get (NMPlatformKernelSupportType type)
{
const NMPlatformLink *pllink;
NMTernary v;
v = nm_platform_kernel_support_get_full (type, FALSE);
@ -1990,6 +1991,12 @@ nmtstp_kernel_support_get (NMPlatformKernelSupportType type)
return v != NM_TERNARY_FALSE;
switch (type) {
case NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED:
pllink = nmtstp_link_bridge_add (NULL, -1, "br-test-11", &nm_platform_lnk_bridge_default);
nmtstp_link_delete (NULL, -1, pllink->ifindex, NULL, TRUE);
v = nm_platform_kernel_support_get_full (type, FALSE);
g_assert (v != NM_TERNARY_DEFAULT);
return v;
default:
g_assert_not_reached ();
}

View file

@ -971,7 +971,9 @@ test_software_detect (gconstpointer user_data)
lnk_bridge.stp_state = TRUE;
lnk_bridge.priority = 22;
lnk_bridge.vlan_protocol = 0x8100;
lnk_bridge.vlan_stats_enabled = TRUE;
lnk_bridge.vlan_stats_enabled = nmtstp_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED)
? TRUE
: FALSE;
lnk_bridge.group_fwd_mask = 8;
lnk_bridge.group_addr = (NMEtherAddr) { { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x08 } };
lnk_bridge.mcast_snooping = TRUE;
@ -1360,7 +1362,6 @@ test_software_detect (gconstpointer user_data)
const NMPlatformLnkBridge *plnk = &lnk->lnk_bridge;
g_assert (plnk == nm_platform_link_get_lnk_bridge (NM_PLATFORM_GET, ifindex, NULL));
g_assert_cmpint (nm_platform_lnk_bridge_cmp (&lnk_bridge, plnk), ==, 0);
g_assert_cmpint (plnk->forward_delay , ==, 1560);
g_assert_cmpint (plnk->hello_time , ==, 150);
g_assert_cmpint (plnk->max_age , ==, 2100);
@ -1368,7 +1369,7 @@ test_software_detect (gconstpointer user_data)
g_assert_cmpint (plnk->stp_state , ==, TRUE);
g_assert_cmpint (plnk->priority , ==, 22);
g_assert_cmpint (plnk->vlan_protocol , ==, 0x8100);
g_assert_cmpint (plnk->vlan_stats_enabled , ==, TRUE);
g_assert_cmpint (plnk->vlan_stats_enabled , ==, lnk_bridge.vlan_stats_enabled);
g_assert_cmpint (plnk->group_fwd_mask , ==, 8);
g_assert_cmpint (plnk->mcast_snooping , ==, TRUE);
g_assert_cmpint (plnk->mcast_router , ==, 1);
@ -1382,7 +1383,7 @@ test_software_detect (gconstpointer user_data)
g_assert_cmpint (plnk->mcast_query_interval , ==, 12000);
g_assert_cmpint (plnk->mcast_query_response_interval , ==, 5200);
g_assert_cmpint (plnk->mcast_startup_query_interval , ==, 3000);
g_assert_cmpint (nm_platform_lnk_bridge_cmp (&lnk_bridge, plnk), ==, 0);
break;
}
case NM_LINK_TYPE_GRE: {