]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: bridge: add support for IFLA_BR_FDB_MAX_LEARNED
authorGregor Herburger <gregor.herburger@ew.tq-group.com>
Thu, 20 Jun 2024 14:10:24 +0000 (16:10 +0200)
committerGregor Herburger <gregor.herburger@ew.tq-group.com>
Mon, 22 Jul 2024 08:27:56 +0000 (10:27 +0200)
Since Linux commit ddd1ad68826d ("net: bridge: Add netlink knobs for number
/ max learned FDB entries") [1] it is possible to limit to number of
dynamically learned fdb entries per bridge.

Add support to the systemd netdev bridge for the new netlink attribute
IFLA_BR_FDB_MAX_LEARNED.

[1] https://lore.kernel.org/all/20231016-fdb_limit-v5-0-32cddff87758@avm.de/

Signed-off-by: Gregor Herburger <gregor.herburger@ew.tq-group.com>
man/systemd.netdev.xml
src/libsystemd/sd-netlink/netlink-types-rtnl.c
src/network/netdev/bridge.c
src/network/netdev/bridge.h
src/network/netdev/netdev-gperf.gperf

index 4fba78895069dc071ccca276047ef2722e497837..6a217d9cae0fc7602509253288f721d4933f7c5e 100644 (file)
           <xi:include href="version-info.xml" xpointer="v243"/>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>FDBMaxLearned=</varname></term>
+        <listitem>
+          <para>Specifies the maximum number of learned Ethernet addresses for the bridge. When the limit is
+          reached, no more addresses are learned. When unset, the kernel's default will be used. 0 disables the limit.
+          </para>
+
+          <xi:include href="version-info.xml" xpointer="v257"/>
+        </listitem>
+      </varlistentry>
     </variablelist>
   </refsect1>
 
index e39a75cfe475abd08fc61946c3697b01b3fc31c2..4cd54a3df5586dc338799f6bba8f5df733293edf 100644 (file)
@@ -173,6 +173,7 @@ static const NLAPolicy rtnl_link_info_data_bridge_policies[] = {
         [IFLA_BR_MCAST_MLD_VERSION]          = BUILD_POLICY(U8),
         [IFLA_BR_VLAN_STATS_PER_PORT]        = BUILD_POLICY(U8),
         [IFLA_BR_MULTI_BOOLOPT]              = BUILD_POLICY_WITH_SIZE(BINARY, sizeof(struct br_boolopt_multi)),
+        [IFLA_BR_FDB_MAX_LEARNED]            = BUILD_POLICY(U32),
 };
 
 static const NLAPolicy rtnl_link_info_data_can_policies[] = {
index d426c0c5019f03e4118cadc05feb8e1bc4e2b518..27f39164767ccff94cee133fc8f0a126b4c226b1 100644 (file)
@@ -137,6 +137,12 @@ static int netdev_bridge_post_create_message(NetDev *netdev, sd_netlink_message
                         return r;
         }
 
+        if (b->fdb_max_learned_set) {
+                r = sd_netlink_message_append_u32(req, IFLA_BR_FDB_MAX_LEARNED, b->fdb_max_learned);
+                if (r < 0)
+                        return r;
+        }
+
         r = sd_netlink_message_close_container(req);
         if (r < 0)
                 return r;
@@ -230,6 +236,40 @@ int config_parse_bridge_port_priority(
                         prio);
 }
 
+int config_parse_bridge_fdb_max_learned(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Bridge *b = ASSERT_PTR(userdata);
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                b->fdb_max_learned_set = false;
+                return 0;
+        }
+
+        r = config_parse_uint32_bounded(unit, filename, line, section, section_line, lvalue, rvalue,
+                                        0, UINT32_MAX, true, &b->fdb_max_learned);
+        if (r <= 0)
+                return r;
+
+        b->fdb_max_learned_set = true;
+        return 1;
+}
+
 static void bridge_init(NetDev *netdev) {
         Bridge *b = BRIDGE(netdev);
 
index 72dd3e42059066c72b05b3d067df5873110d3b37..7be00e1063715c4eda66505075d1079fccd026e9 100644 (file)
@@ -19,6 +19,8 @@ typedef struct Bridge {
         uint16_t group_fwd_mask;
         uint16_t default_pvid;
         uint8_t igmp_version;
+        uint32_t fdb_max_learned;
+        bool fdb_max_learned_set;
 
         usec_t forward_delay;
         usec_t hello_time;
@@ -44,3 +46,4 @@ MulticastRouter multicast_router_from_string(const char *s) _pure_;
 CONFIG_PARSER_PROTOTYPE(config_parse_multicast_router);
 CONFIG_PARSER_PROTOTYPE(config_parse_bridge_igmp_version);
 CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority);
+CONFIG_PARSER_PROTOTYPE(config_parse_bridge_fdb_max_learned);
index 4883a2652d4639fc9a95e8a7301abcaab9e7d6e2..8325c8779da1c005d24e685f1d8baa12b06077d2 100644 (file)
@@ -234,6 +234,7 @@ Bridge.VLANFiltering,                     config_parse_tristate,
 Bridge.VLANProtocol,                      config_parse_vlanprotocol,                 0,                             offsetof(Bridge, vlan_protocol)
 Bridge.STP,                               config_parse_tristate,                     0,                             offsetof(Bridge, stp)
 Bridge.MulticastIGMPVersion,              config_parse_uint8,                        0,                             offsetof(Bridge, igmp_version)
+Bridge.FDBMaxLearned,                     config_parse_bridge_fdb_max_learned,       0,                             offsetof(Bridge, fdb_max_learned)
 VRF.TableId,                              config_parse_uint32,                       0,                             offsetof(Vrf, table) /* deprecated */
 VRF.Table,                                config_parse_uint32,                       0,                             offsetof(Vrf, table)
 BareUDP.DestinationPort,                  config_parse_ip_port,                      0,                             offsetof(BareUDP, dest_port)