Skip to content

Commit

Permalink
route: add support for layer 3 filtering on bridges
Browse files Browse the repository at this point in the history
  • Loading branch information
Cordell-O authored and thom311 committed Apr 3, 2024
1 parent 3646398 commit 19d48b0
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/netlink/route/link/bridge_info.h
Expand Up @@ -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
}
Expand Down
96 changes: 96 additions & 0 deletions lib/route/link/bridge_info.c
Expand Up @@ -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 */
Expand All @@ -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] = {
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions libnl-route-3.sym
Expand Up @@ -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;
Expand Down

0 comments on commit 19d48b0

Please sign in to comment.