summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCordell O'Leary <cordell.oleary@alliedtelesis.co.nz>2024-04-03 10:55:58 +1300
committerThomas Haller <thaller@redhat.com>2024-04-03 08:16:51 +0200
commit19d48b0fe924085f28c9410fae448d385f5f9a23 (patch)
treeb1fb76559ec85d3b28e9a1d4cb37f480ca8dc2fc
parent3646398d57e2da7d3f6ef7979007a7db2e84644f (diff)
downloadlibnl-19d48b0fe924085f28c9410fae448d385f5f9a23.tar.gz
route: add support for layer 3 filtering on bridges
https://github.com/thom311/libnl/pull/373
-rw-r--r--include/netlink/route/link/bridge_info.h6
-rw-r--r--lib/route/link/bridge_info.c96
-rw-r--r--libnl-route-3.sym3
3 files changed, 105 insertions, 0 deletions
diff --git a/include/netlink/route/link/bridge_info.h b/include/netlink/route/link/bridge_info.h
index e8448a46..bb7bf0b6 100644
--- a/include/netlink/route/link/bridge_info.h
+++ b/include/netlink/route/link/bridge_info.h
@@ -37,6 +37,12 @@ extern void rtnl_link_bridge_set_vlan_stats_enabled(struct rtnl_link *link,
uint8_t vlan_stats_enabled);
extern int rtnl_link_bridge_get_vlan_stats_enabled(struct rtnl_link *link,
uint8_t *vlan_stats_enabled);
+extern void rtnl_link_bridge_set_nf_call_iptables(struct rtnl_link *link,
+ uint8_t call_enabled);
+extern void rtnl_link_bridge_set_nf_call_ip6tables(struct rtnl_link *link,
+ uint8_t call_enabled);
+extern void rtnl_link_bridge_set_nf_call_arptables(struct rtnl_link *link,
+ uint8_t call_enabled);
#ifdef __cplusplus
}
diff --git a/lib/route/link/bridge_info.c b/lib/route/link/bridge_info.c
index 311e947b..5d69b5ca 100644
--- a/lib/route/link/bridge_info.c
+++ b/lib/route/link/bridge_info.c
@@ -23,6 +23,9 @@
#define BRIDGE_ATTR_VLAN_STATS_ENABLED (1 << 2)
#define BRIDGE_ATTR_AGEING_TIME (1 << 3)
#define BRIDGE_ATTR_VLAN_DEFAULT_PVID (1 << 4)
+#define BRIDGE_ATTR_NF_CALL_IPTABLES (1 << 5)
+#define BRIDGE_ATTR_NF_CALL_IP6TABLES (1 << 6)
+#define BRIDGE_ATTR_NF_CALL_ARPTABLES (1 << 7)
struct bridge_info {
uint32_t ce_mask; /* to support attr macros */
@@ -31,6 +34,9 @@ struct bridge_info {
uint16_t b_vlan_default_pvid;
uint8_t b_vlan_filtering;
uint8_t b_vlan_stats_enabled;
+ uint8_t b_nf_call_iptables;
+ uint8_t b_nf_call_ip6tables;
+ uint8_t b_nf_call_arptables;
};
static const struct nla_policy bi_attrs_policy[IFLA_BR_MAX + 1] = {
@@ -39,6 +45,9 @@ static const struct nla_policy bi_attrs_policy[IFLA_BR_MAX + 1] = {
[IFLA_BR_VLAN_FILTERING] = { .type = NLA_U8 },
[IFLA_BR_VLAN_PROTOCOL] = { .type = NLA_U16 },
[IFLA_BR_VLAN_STATS_ENABLED] = { .type = NLA_U8 },
+ [IFLA_BR_NF_CALL_IPTABLES] = { .type = NLA_U8 },
+ [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NLA_U8 },
+ [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NLA_U8 },
};
static inline struct bridge_info *bridge_info(struct rtnl_link *link)
@@ -109,6 +118,24 @@ static int bridge_info_parse(struct rtnl_link *link, struct nlattr *data,
bi->ce_mask |= BRIDGE_ATTR_VLAN_STATS_ENABLED;
}
+ if (tb[IFLA_BR_NF_CALL_IPTABLES]) {
+ bi->b_nf_call_iptables =
+ nla_get_u8(tb[IFLA_BR_NF_CALL_IPTABLES]);
+ bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IPTABLES;
+ }
+
+ if (tb[IFLA_BR_NF_CALL_IP6TABLES]) {
+ bi->b_nf_call_ip6tables =
+ nla_get_u8(tb[IFLA_BR_NF_CALL_IP6TABLES]);
+ bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IP6TABLES;
+ }
+
+ if (tb[IFLA_BR_NF_CALL_ARPTABLES]) {
+ bi->b_nf_call_arptables =
+ nla_get_u8(tb[IFLA_BR_NF_CALL_ARPTABLES]);
+ bi->ce_mask |= BRIDGE_ATTR_NF_CALL_ARPTABLES;
+ }
+
return 0;
}
@@ -139,6 +166,18 @@ static int bridge_info_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
NLA_PUT_U8(msg, IFLA_BR_VLAN_STATS_ENABLED,
bi->b_vlan_stats_enabled);
+ if (bi->ce_mask & BRIDGE_ATTR_NF_CALL_IPTABLES)
+ NLA_PUT_U8(msg, IFLA_BR_NF_CALL_IPTABLES,
+ bi->b_nf_call_iptables);
+
+ if (bi->ce_mask & BRIDGE_ATTR_NF_CALL_IP6TABLES)
+ NLA_PUT_U8(msg, IFLA_BR_NF_CALL_IP6TABLES,
+ bi->b_nf_call_ip6tables);
+
+ if (bi->ce_mask & BRIDGE_ATTR_NF_CALL_ARPTABLES)
+ NLA_PUT_U8(msg, IFLA_BR_NF_CALL_ARPTABLES,
+ bi->b_nf_call_arptables);
+
nla_nest_end(msg, data);
return 0;
@@ -414,6 +453,63 @@ int rtnl_link_bridge_get_vlan_stats_enabled(struct rtnl_link *link,
return 0;
}
+/**
+ * Set call enabled flag for passing IPv4 traffic to iptables
+ * @arg link Link object of type bridge
+ * @arg call_enabled call enabled boolean flag to set.
+ *
+ * @return void
+ */
+void rtnl_link_bridge_set_nf_call_iptables(struct rtnl_link *link,
+ uint8_t call_enabled)
+{
+ struct bridge_info *bi = bridge_info(link);
+
+ IS_BRIDGE_INFO_ASSERT(link);
+
+ bi->b_nf_call_iptables = call_enabled;
+
+ bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IPTABLES;
+}
+
+/**
+ * Set call enabled flag for passing IPv6 traffic to ip6tables
+ * @arg link Link object of type bridge
+ * @arg call_enabled call enabled boolean flag to set.
+ *
+ * @return void
+ */
+void rtnl_link_bridge_set_nf_call_ip6tables(struct rtnl_link *link,
+ uint8_t call_enabled)
+{
+ struct bridge_info *bi = bridge_info(link);
+
+ IS_BRIDGE_INFO_ASSERT(link);
+
+ bi->b_nf_call_ip6tables = call_enabled;
+
+ bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IP6TABLES;
+}
+
+/**
+ * Set call enabled flag for passing ARP traffic to arptables
+ * @arg link Link object of type bridge
+ * @arg call_enabled call enabled boolean flag to set.
+ *
+ * @return void
+ */
+void rtnl_link_bridge_set_nf_call_arptables(struct rtnl_link *link,
+ uint8_t call_enabled)
+{
+ struct bridge_info *bi = bridge_info(link);
+
+ IS_BRIDGE_INFO_ASSERT(link);
+
+ bi->b_nf_call_arptables = call_enabled;
+
+ bi->ce_mask |= BRIDGE_ATTR_NF_CALL_ARPTABLES;
+}
+
static void _nl_init bridge_info_init(void)
{
rtnl_link_register_info(&bridge_info_ops);
diff --git a/libnl-route-3.sym b/libnl-route-3.sym
index eb4752ab..c9418841 100644
--- a/libnl-route-3.sym
+++ b/libnl-route-3.sym
@@ -1322,6 +1322,9 @@ global:
rtnl_link_bridge_get_vlan_default_pvid;
rtnl_link_bridge_set_ageing_time;
rtnl_link_bridge_set_master;
+ rtnl_link_bridge_set_nf_call_arptables;
+ rtnl_link_bridge_set_nf_call_iptables;
+ rtnl_link_bridge_set_nf_call_ip6tables;
rtnl_link_bridge_set_port_vlan_map_range;
rtnl_link_bridge_set_port_vlan_pvid;
rtnl_link_bridge_unset_port_vlan_map_range;