--- zzzz-none-000/linux-5.15.111/net/bridge/br_input.c 2023-05-11 14:00:40.000000000 +0000 +++ puma7-atom-6670-761/linux-5.15.111/net/bridge/br_input.c 2024-02-07 10:23:29.000000000 +0000 @@ -23,6 +23,13 @@ #include "br_private.h" #include "br_private_tunnel.h" +#ifdef CONFIG_TI_L2_SELECTIVE_FORWARDER +extern int ti_selective_packet_handler (struct sk_buff *skb); +#endif /* CONFIG_TI_L2_SELECTIVE_FORWARDER */ +#ifdef CONFIG_INTEL_L2VPN_L2CP_FORWARD +extern int intel_l2vpn_packet_handler (struct sk_buff *skb, int *l2vpnRelate); +#endif /* CONFIG_INTEL_L2VPN_L2CP_FORWARD */ + static int br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb) { @@ -97,13 +104,39 @@ nbp_switchdev_frame_mark(p, skb); - /* insert into forwarding database after filtering to avoid spoofing */ br = p->br; + +#ifdef CONFIG_BRIDGE_NETFILTER +#ifdef CONFIG_BRIDGE_EBT_FORWARD + /* Check for predetermined forwarding ebtables rule */ + if (skb->bridge_forward_port) { + BR_INPUT_SKB_CB(skb)->brdev = br->dev; + + local_rcv = !!(br->dev->flags & IFF_PROMISC); + br_forward(skb->bridge_forward_port, skb, local_rcv, false); + + if(local_rcv) { + if(skb) + return br_pass_frame_up(skb); + } + else { + goto out; + } + } +#endif +#endif + + /* insert into forwarding database after filtering to avoid spoofing */ if (p->flags & BR_LEARNING) br_fdb_update(br, p, eth_hdr(skb)->h_source, vid, 0); local_rcv = !!(br->dev->flags & IFF_PROMISC); if (is_multicast_ether_addr(eth_hdr(skb)->h_dest)) { +#ifdef CONFIG_TI_L2_SELECTIVE_FORWARDER + if (ti_selective_packet_handler(skb) != 0) { + goto out; + } +#endif /* CONFIG_TI_L2_SELECTIVE_FORWARDER */ /* by definition the broadcast is also a multicast address */ if (is_broadcast_ether_addr(eth_hdr(skb)->h_dest)) { pkt_type = BR_PKT_BROADCAST; @@ -171,8 +204,16 @@ dst->used = now; br_forward(dst->dst, skb, local_rcv, false); } else { - if (!mcast_hit) +#ifdef CONFIG_TI_L2_SELECTIVE_FORWARDER + if (ti_selective_packet_handler(skb) != 0) + goto out; +#endif /* CONFIG_TI_L2_SELECTIVE_FORWARDER */ + if (!mcast_hit) { +#ifdef CONFIG_TI_PACKET_PROCESSOR + ti_hil_pp_event (TI_BRIDGE_PACKET_FLOODED, (void*)skb); +#endif /* CONFIG_TI_PACKET_PROCESSOR */ br_flood(br, skb, pkt_type, local_rcv, false); + } else br_multicast_flood(mdst, skb, brmctx, local_rcv, false); } @@ -204,7 +245,10 @@ /* note: already called with rcu_read_lock */ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { - __br_handle_local_finish(skb); + struct net_bridge_port *p = br_port_get_rcu(skb->dev); + + if (p->state != BR_STATE_DISABLED) + __br_handle_local_finish(skb); /* return 1 to signal the okfn() was called so it's ok to use the skb */ return 1; @@ -288,6 +332,9 @@ struct sk_buff *skb = *pskb; const unsigned char *dest = eth_hdr(skb)->h_dest; +#ifdef CONFIG_INTEL_L2VPN_L2CP_FORWARD + int l2vpnRelated = 0; +#endif /* CONFIG_INTEL_L2VPN_L2CP_FORWARD */ if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) return RX_HANDLER_PASS; @@ -300,13 +347,35 @@ memset(skb->cb, 0, sizeof(struct br_input_skb_cb)); +#ifdef CONFIG_TI_DOCSIS_INPUT_DEV + if(!skb->ti_docsis_input_dev) { + skb->ti_docsis_input_dev = skb->dev; + } +#endif + p = br_port_get_rcu(skb->dev); if (p->flags & BR_VLAN_TUNNEL) br_handle_ingress_vlan_tunnel(skb, p, nbp_vlan_group_rcu(p)); + if (WARN(p == NULL, "%s - %d: br_port_get_rcu(skb->dev) returned NULL, dropping packet (dev == %s)", \ + __func__, __LINE__, skb->dev ? skb->dev->name : "NULL")) + { + goto drop; + } + if (unlikely(is_link_local_ether_addr(dest))) { u16 fwd_mask = p->br->group_fwd_mask_required; +#ifdef CONFIG_INTEL_L2VPN_L2CP_FORWARD + if (!intel_l2vpn_packet_handler(skb, &l2vpnRelated)) + { + if (l2vpnRelated) + { + goto forward; + } + } +#endif /* CONFIG_INTEL_L2VPN_L2CP_FORWARD */ + /* * See IEEE 802.1D Table 7-10 Reserved addresses * @@ -369,11 +438,29 @@ forward: switch (p->state) { + case BR_STATE_DISABLED: + if (skb->protocol == htons(ETH_P_PAE)) { + if (ether_addr_equal(p->br->dev->dev_addr, dest)) + skb->pkt_type = PACKET_HOST; + + if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, + dev_net(skb->dev), NULL, skb, skb->dev, NULL, + br_handle_local_finish) == 1) { + return RX_HANDLER_PASS; + } + } + goto drop; + case BR_STATE_FORWARDING: case BR_STATE_LEARNING: if (ether_addr_equal(p->br->dev->dev_addr, dest)) skb->pkt_type = PACKET_HOST; - +#ifdef CONFIG_BRIDGE_NETFILTER +#ifdef CONFIG_BRIDGE_EBT_FORWARD + /* Initialize bridge bridge_forward_port so prerouting rule can populate it */ + skb->bridge_forward_port = NULL; +#endif +#endif return nf_hook_bridge_pre(skb, pskb); default: drop: