From e0bd527a8d679b249761f2d405774a3376bfd237 Mon Sep 17 00:00:00 2001 From: Felix Fietkau <nbd@nbd.name> Date: Fri, 7 Jul 2017 17:20:03 +0200 Subject: [PATCH] bridge: port isolate Isolating individual bridge ports Signed-off-by: Felix Fietkau <nbd@nbd.name> --- include/linux/if_bridge.h | 1 + net/bridge/br_forward.c | 5 +++++ net/bridge/br_input.c | 3 +++ net/bridge/br_sysfs_if.c | 2 ++ 4 files changed, 11 insertions(+) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index debc9d590..0911c8cd5 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -47,6 +47,7 @@ struct br_ip_list { #define BR_PROXYARP_WIFI BIT(10) #define BR_MCAST_FLOOD BIT(11) #define BR_MULTICAST_TO_UNICAST BIT(12) +#define BR_ISOLATE_MODE BIT(13) #define BR_DEFAULT_AGEING_TIME (300 * HZ) diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 15cf9b916..c29b4d5be 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -162,6 +162,9 @@ static int deliver_clone(const struct net_bridge_port *prev, void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, bool local_rcv, bool local_orig) { + if (to->flags & BR_ISOLATE_MODE) + to = NULL; + if (to && should_deliver(to, skb)) { if (local_rcv) deliver_clone(to, skb, local_orig); @@ -236,6 +239,8 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb, struct net_bridge_port *p; list_for_each_entry_rcu(p, &br->port_list, list) { + if (!local_orig && (p->flags & BR_ISOLATE_MODE)) + continue; /* Do not flood unicast traffic to ports that turn it off */ if (pkt_type == BR_PKT_UNICAST && !(p->flags & BR_FLOOD)) continue; diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 5d1f52519..d1d189b64 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -175,6 +175,9 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb if (IS_ENABLED(CONFIG_INET) && skb->protocol == htons(ETH_P_ARP)) br_do_proxy_arp(skb, br, vid, p); + if (p->flags & BR_ISOLATE_MODE) + return br_pass_frame_up(skb); + switch (pkt_type) { case BR_PKT_MULTICAST: mdst = br_mdb_get(br, skb, vid); diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c index 228ebcd4f..28aa43f56 100644 --- a/net/bridge/br_sysfs_if.c +++ b/net/bridge/br_sysfs_if.c @@ -172,6 +172,7 @@ BRPORT_ATTR_FLAG(unicast_flood, BR_FLOOD); BRPORT_ATTR_FLAG(proxyarp, BR_PROXYARP); BRPORT_ATTR_FLAG(proxyarp_wifi, BR_PROXYARP_WIFI); BRPORT_ATTR_FLAG(multicast_flood, BR_MCAST_FLOOD); +BRPORT_ATTR_FLAG(isolate_mode, BR_ISOLATE_MODE); #ifdef CONFIG_BRIDGE_IGMP_SNOOPING static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf) @@ -220,6 +221,7 @@ static const struct brport_attribute *brport_attrs[] = { &brport_attr_proxyarp, &brport_attr_proxyarp_wifi, &brport_attr_multicast_flood, + &brport_attr_isolate_mode, NULL }; -- GitLab