^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Forwarding decision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Linux ethernet bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Lennert Buytenhek <buytenh@gnu.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/netpoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/netfilter_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "br_private.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* Don't forward packets to originating port or forwarding disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static inline int should_deliver(const struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) const struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct net_bridge_vlan_group *vg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) vg = nbp_vlan_group_rcu(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return ((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) p->state == BR_STATE_FORWARDING && br_allowed_egress(vg, skb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) nbp_switchdev_allowed_egress(p, skb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) !br_skb_isolated(p, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) skb_push(skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (!is_skb_forwardable(skb->dev, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) br_drop_fake_rtable(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (skb->ip_summed == CHECKSUM_PARTIAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) (skb->protocol == htons(ETH_P_8021Q) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) skb->protocol == htons(ETH_P_8021AD))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (!__vlan_get_protocol(skb, skb->protocol, &depth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) skb_set_network_header(skb, depth);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) dev_queue_xmit(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) EXPORT_SYMBOL_GPL(br_dev_queue_push_xmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int br_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) skb->tstamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return NF_HOOK(NFPROTO_BRIDGE, NF_BR_POST_ROUTING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) net, sk, skb, NULL, skb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) br_dev_queue_push_xmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) EXPORT_SYMBOL_GPL(br_forward_finish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static void __br_forward(const struct net_bridge_port *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct sk_buff *skb, bool local_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct net_bridge_vlan_group *vg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct net_device *indev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int br_hook;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) vg = nbp_vlan_group_rcu(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) skb = br_handle_vlan(to->br, to, vg, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) indev = skb->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) skb->dev = to->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!local_orig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (skb_warn_if_lro(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) br_hook = NF_BR_FORWARD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) skb_forward_csum(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) net = dev_net(indev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (unlikely(netpoll_tx_running(to->br->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) skb_push(skb, ETH_HLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (!is_skb_forwardable(skb->dev, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) br_netpoll_send_skb(to, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) br_hook = NF_BR_LOCAL_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) indev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) NF_HOOK(NFPROTO_BRIDGE, br_hook,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) net, NULL, skb, indev, skb->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) br_forward_finish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static int deliver_clone(const struct net_bridge_port *prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct sk_buff *skb, bool local_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) skb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) dev->stats.tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) __br_forward(prev, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * br_forward - forward a packet to a specific port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * @to: destination port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @skb: packet being forwarded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @local_rcv: packet will be received locally after forwarding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * @local_orig: packet is locally originated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * Should be called with rcu_read_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) void br_forward(const struct net_bridge_port *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct sk_buff *skb, bool local_rcv, bool local_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (unlikely(!to))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* redirect to backup link if the destination port is down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (rcu_access_pointer(to->backup_port) && !netif_carrier_ok(to->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct net_bridge_port *backup_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) backup_port = rcu_dereference(to->backup_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (unlikely(!backup_port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) to = backup_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (should_deliver(to, skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (local_rcv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) deliver_clone(to, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) __br_forward(to, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!local_rcv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) EXPORT_SYMBOL_GPL(br_forward);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static struct net_bridge_port *maybe_deliver(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct net_bridge_port *prev, struct net_bridge_port *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct sk_buff *skb, bool local_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u8 igmp_type = br_multicast_igmp_type(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (!should_deliver(p, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (!prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) err = deliver_clone(prev, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) br_multicast_count(p->br, p, skb, igmp_type, BR_MCAST_DIR_TX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* called under rcu_read_lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void br_flood(struct net_bridge *br, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) enum br_pkt_type pkt_type, bool local_rcv, bool local_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) struct net_bridge_port *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct net_bridge_port *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) list_for_each_entry_rcu(p, &br->port_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* Do not flood unicast traffic to ports that turn it off, nor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * other traffic if flood off, except for traffic we originate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) switch (pkt_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case BR_PKT_UNICAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!(p->flags & BR_FLOOD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case BR_PKT_MULTICAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case BR_PKT_BROADCAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* Do not flood to ports that enable proxy ARP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (p->flags & BR_PROXYARP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if ((p->flags & (BR_PROXYARP_WIFI | BR_NEIGH_SUPPRESS)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) BR_INPUT_SKB_CB(skb)->proxyarp_replied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) prev = maybe_deliver(prev, p, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (IS_ERR(prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (!prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (local_rcv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) deliver_clone(prev, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) __br_forward(prev, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!local_rcv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void maybe_deliver_addr(struct net_bridge_port *p, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) const unsigned char *addr, bool local_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) const unsigned char *src = eth_hdr(skb)->h_source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (!should_deliver(p, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /* Even with hairpin, no soliloquies - prevent breaking IPv6 DAD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (skb->dev == p->dev && ether_addr_equal(src, addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) skb = skb_copy(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dev->stats.tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (!is_broadcast_ether_addr(addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) memcpy(eth_hdr(skb)->h_dest, addr, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) __br_forward(p, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* called with rcu_read_lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) void br_multicast_flood(struct net_bridge_mdb_entry *mdst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) bool local_rcv, bool local_orig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct net_bridge *br = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) struct net_bridge_port *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct net_bridge_port_group *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) bool allow_mode_include = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct hlist_node *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) rp = rcu_dereference(hlist_first_rcu(&br->router_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (mdst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) p = rcu_dereference(mdst->ports);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (br_multicast_should_handle_mode(br, mdst->addr.proto) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) br_multicast_is_star_g(&mdst->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) allow_mode_include = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) while (p || rp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct net_bridge_port *port, *lport, *rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) lport = p ? p->key.port : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) rport = hlist_entry_safe(rp, struct net_bridge_port, rlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if ((unsigned long)lport > (unsigned long)rport) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) port = lport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (port->flags & BR_MULTICAST_TO_UNICAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) maybe_deliver_addr(lport, skb, p->eth_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto delivered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if ((!allow_mode_include &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) p->filter_mode == MCAST_INCLUDE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) (p->flags & MDB_PG_FLAGS_BLOCKED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) goto delivered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) port = rport;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) prev = maybe_deliver(prev, port, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (IS_ERR(prev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) delivered:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) if ((unsigned long)lport >= (unsigned long)port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) p = rcu_dereference(p->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if ((unsigned long)rport >= (unsigned long)port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) rp = rcu_dereference(hlist_next_rcu(rp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (!prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) if (local_rcv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) deliver_clone(prev, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) __br_forward(prev, skb, local_orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (!local_rcv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) #endif