net: bridge: Fix for co-located mode

Issue point:

1.qca-hyfi-bridge calls the HyFi-hooks for enabling the co-located mode.
    a. hyfi_bridge_get_dst and br_get_dst_hook functions are passed
        as arguments in a rcu_assign_pointer function.
    b. br_get_dst_hook implementations should be available in the
       br_dev_xmit kernel function. But currently br_get_dst_hook
       implementations are missing in br_dev_xmit.
Fix:

1. For enabling co-located-agent-mode and ieee1905-packet-transfer this
   HyFi-hook (br_get_dst_hook) are made available in br_dev_xmit function.
     a. Added the br_get_dst_hook and get_dst_hook in the required
        files(net/bridge/br_input.c & net/bridge/br_device.c)

Change-Id: Iac43ea347c83276971816029a940818e99752710
Signed-off-by: Desireddy Suresh Kumar Reddy <quic_dsureshk@quicinc.com>
This commit is contained in:
Desireddy Suresh Kumar Reddy 2024-02-09 16:49:34 +05:30 • committed by Xinyue Ling
commit a3e616cc0d
3 changed files with 46 additions and 4 deletions

View file

@ -162,5 +162,9 @@ extern br_notify_hook_t __rcu *br_notify_hook;
typedef int (br_multicast_handle_hook_t)(const struct net_bridge_port *src,
struct sk_buff *skb);
extern br_multicast_handle_hook_t __rcu *br_multicast_handle_hook;
typedef struct net_bridge_port *br_get_dst_hook_t(
const struct net_bridge_port *src,
struct sk_buff **skb);
extern br_get_dst_hook_t __rcu *br_get_dst_hook;
#endif
#endif

View file

@ -34,6 +34,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
const struct nf_br_ops *nf_ops;
const unsigned char *dest;
u16 vid = 0;
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
struct net_bridge_port *pdst;
br_get_dst_hook_t *get_dst_hook;
#endif
if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) {
kfree_skb(skb);
@ -82,6 +86,10 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
br_do_suppress_nd(skb, br, vid, NULL, msg);
}
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
get_dst_hook = rcu_dereference(br_get_dst_hook);
#endif
dest = eth_hdr(skb)->h_dest;
if (is_broadcast_ether_addr(dest)) {
br_flood(br, skb, BR_PKT_BROADCAST, false, true);
@ -107,11 +115,24 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
br_multicast_flood(mdst, skb, false, true);
else
br_flood(br, skb, BR_PKT_MULTICAST, false, true);
} else if ((dst = br_fdb_find_rcu(br, dest, vid)) != NULL) {
br_forward(dst->dst, skb, false, true);
} else {
br_flood(br, skb, BR_PKT_UNICAST, false, true);
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
pdst = __br_get(get_dst_hook, NULL, NULL, &skb);
if (pdst) {
if (!skb)
goto out;
br_forward(pdst, skb, false, true);
} else
#endif
{
dst = br_fdb_find_rcu(br, dest, vid);
if (dst)
br_forward(dst->dst, skb, false, true);
else
br_flood(br, skb, BR_PKT_UNICAST, false, true);
}
}
out:
rcu_read_unlock();
return NETDEV_TX_OK;

View file

@ -33,6 +33,11 @@ br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb)
/* Hook for external Multicast handler */
br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly;
EXPORT_SYMBOL(br_multicast_handle_hook);
/* Hook for external forwarding logic */
br_get_dst_hook_t __rcu *br_get_dst_hook __read_mostly;
EXPORT_SYMBOL_GPL(br_get_dst_hook);
#endif
int br_pass_frame_up(struct sk_buff *skb)
@ -94,6 +99,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
struct net_bridge *br;
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
br_multicast_handle_hook_t *multicast_handle_hook;
struct net_bridge_port *pdst = NULL;
br_get_dst_hook_t *get_dst_hook = rcu_dereference(br_get_dst_hook);
#endif
u16 vid = 0;
@ -168,7 +175,17 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
}
break;
case BR_PKT_UNICAST:
dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid);
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
pdst = __br_get(get_dst_hook, NULL, p, &skb);
if (pdst) {
if (!skb)
goto out;
} else
#endif
{
dst = br_fdb_find_rcu(br, eth_hdr(skb)->h_dest, vid);
}
break;
default:
break;
}