/* Mark the skb for forwarding offload early so that br_handle_vlan() * can know whether to pop the VLAN header on egress or keep it.
*/
nbp_switchdev_frame_mark_tx_fwd_offload(to, skb);
vg = nbp_vlan_group_rcu(to);
skb = br_handle_vlan(to->br, to, vg, skb); if (!skb) return;
indev = skb->dev;
skb->dev = to->dev; if (!local_orig) { if (skb_warn_if_lro(skb)) {
kfree_skb(skb); return;
}
br_hook = NF_BR_FORWARD;
skb_forward_csum(skb);
net = dev_net(indev);
} else { if (unlikely(netpoll_tx_running(to->br->dev))) {
skb_push(skb, ETH_HLEN); if (!is_skb_forwardable(skb->dev, skb))
kfree_skb(skb); else
br_netpoll_send_skb(to, skb); return;
}
br_hook = NF_BR_LOCAL_OUT;
net = dev_net(skb->dev);
indev = NULL;
}
/** * br_forward - forward a packet to a specific port * @to: destination port * @skb: packet being forwarded * @local_rcv: packet will be received locally after forwarding * @local_orig: packet is locally originated * * Should be called with rcu_read_lock.
*/ void br_forward(conststruct net_bridge_port *to, struct sk_buff *skb, bool local_rcv, bool local_orig)
{ if (unlikely(!to)) goto out;
/* redirect to backup link if the destination port is down */ if (rcu_access_pointer(to->backup_port) &&
(!netif_carrier_ok(to->dev) || !netif_running(to->dev))) { struct net_bridge_port *backup_port;
backup_port = rcu_dereference(to->backup_port); if (unlikely(!backup_port)) goto out;
BR_INPUT_SKB_CB(skb)->backup_nhid = READ_ONCE(to->backup_nhid);
to = backup_port;
}
if (should_deliver(to, skb)) { if (local_rcv)
deliver_clone(to, skb, local_orig); else
__br_forward(to, skb, local_orig); return;
}
out: if (!local_rcv)
kfree_skb(skb);
}
EXPORT_SYMBOL_GPL(br_forward);
list_for_each_entry_rcu(p, &br->port_list, list) { /* Do not flood unicast traffic to ports that turn it off, nor * other traffic if flood off, except for traffic we originate
*/ switch (pkt_type) { case BR_PKT_UNICAST: if (!(p->flags & BR_FLOOD)) continue; break; case BR_PKT_MULTICAST: if (!(p->flags & BR_MCAST_FLOOD) && skb->dev != br->dev) continue; break; case BR_PKT_BROADCAST: if (!(p->flags & BR_BCAST_FLOOD) && skb->dev != br->dev) continue; break;
}
/* Do not flood to ports that enable proxy ARP */ if (p->flags & BR_PROXYARP) continue; if (BR_INPUT_SKB_CB(skb)->proxyarp_replied &&
((p->flags & BR_PROXYARP_WIFI) ||
br_is_neigh_suppress_enabled(p, vid))) continue;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.