bridge: Port Hy-Fi bridging hooks

Changes to port Hy-Fi bridging hooks and to export
br_fdb_find_rcu symbol.

Change-Id: Ife2a9ac76e02fff56b8c4acaa97794df7e98863d
Signed-off-by: Muthuchamy Kumar <quic_muthucha@quicinc.com>
Signed-off-by: Pooventhiran G <quic_pooventh@quicinc.com>
This commit is contained in:
Pooventhiran G 2022-01-13 19:07:21 +05:30 committed by Gerrit - the friendly Code Review server
parent f89c40b130
commit af60234af1
8 changed files with 84 additions and 1 deletions

View File

@ -50,6 +50,11 @@ struct br_ip_list {
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
//Handle HYFI_BRIDGING hooks related stuffs, only if HYFI_BRIDGE_HOOKS is defined
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
struct net_bridge_port;
#endif
extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
#ifdef CONFIG_ENABLE_SFE
@ -151,4 +156,11 @@ br_port_flag_is_set(const struct net_device *dev, unsigned long flag)
}
#endif
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
typedef void (br_notify_hook_t)(int group, int event, const void *ptr);
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;
#endif
#endif

View File

@ -61,3 +61,15 @@ config BRIDGE_VLAN_FILTERING
Say N to exclude this support and reduce the binary size.
If unsure, say Y.
config HYFI_BRIDGE_HOOKS
bool "Port Hy-Fi Bridging Hooks"
depends on BRIDGE
depends on QGKI
default y
help
If you say Y here, then the Port Hy-Fi Bridging Hooks will be enabled.
Say N to exclude this support.
If unsure, say Y.

View File

@ -394,6 +394,12 @@ static void __exit br_deinit(void)
br_fdb_fini();
}
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
/* Hook for bridge event notifications */
br_notify_hook_t __rcu *br_notify_hook __read_mostly;
EXPORT_SYMBOL(br_notify_hook);
#endif
module_init(br_init)
module_exit(br_deinit)
MODULE_LICENSE("GPL");

View File

@ -81,6 +81,12 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
if (is_broadcast_ether_addr(dest)) {
br_flood(br, skb, BR_PKT_BROADCAST, false, true);
} else if (is_multicast_ether_addr(dest)) {
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
br_multicast_handle_hook_t *multicast_handle_hook =
rcu_dereference(br_multicast_handle_hook);
if (!__br_get(multicast_handle_hook, true, NULL, skb))
goto out;
#endif
if (unlikely(netpoll_tx_running(dev))) {
br_flood(br, skb, BR_PKT_MULTICAST, false, true);
goto out;

View File

@ -147,6 +147,10 @@ struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
return fdb_find_rcu(&br->fdb_hash_tbl, addr, vid);
}
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
EXPORT_SYMBOL(br_fdb_find_rcu);
#endif
/* When a static FDB entry is added, the mac address from the entry is
* added to the bridge private HW address list and all required ports
* are then updated with the new information.
@ -709,6 +713,9 @@ static void fdb_notify(struct net_bridge *br,
kfree_skb(skb);
goto errout;
}
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
__br_notify(RTNLGRP_NEIGH, type, fdb);
#endif
rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
return;
errout:

View File

@ -29,7 +29,13 @@ br_netif_receive_skb(struct net *net, struct sock *sk, struct sk_buff *skb)
return netif_receive_skb(skb);
}
static int br_pass_frame_up(struct sk_buff *skb)
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
/* Hook for external Multicast handler */
br_multicast_handle_hook_t __rcu *br_multicast_handle_hook __read_mostly;
EXPORT_SYMBOL(br_multicast_handle_hook);
#endif
int br_pass_frame_up(struct sk_buff *skb)
{
struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
struct net_bridge *br = netdev_priv(brdev);
@ -66,6 +72,10 @@ static int br_pass_frame_up(struct sk_buff *skb)
br_netif_receive_skb);
}
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
EXPORT_SYMBOL(br_pass_frame_up);
#endif
/* note: already called with rcu_read_lock */
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
{
@ -75,6 +85,9 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
struct net_bridge_mdb_entry *mdst;
bool local_rcv, mcast_hit = false;
struct net_bridge *br;
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
br_multicast_handle_hook_t *multicast_handle_hook;
#endif
u16 vid = 0;
if (!p || p->state == BR_STATE_DISABLED)
@ -128,6 +141,11 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
switch (pkt_type) {
case BR_PKT_MULTICAST:
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
multicast_handle_hook = rcu_dereference(br_multicast_handle_hook);
if (!__br_get(multicast_handle_hook, true, p, skb))
goto out;
#endif
mdst = br_mdb_get(br, skb, vid);
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
br_multicast_querier_exists(br, eth_hdr(skb))) {

View File

@ -499,6 +499,9 @@ void br_ifinfo_notify(int event, const struct net_bridge *br,
kfree_skb(skb);
goto errout;
}
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
__br_notify(RTNLGRP_LINK, event, port);
#endif
rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
return;
errout:

View File

@ -18,6 +18,9 @@
#include <linux/if_vlan.h>
#include <linux/rhashtable.h>
#include <linux/refcount.h>
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
#include <linux/export.h>
#endif
#define BR_HASH_BITS 8
#define BR_HASH_SIZE (1 << BR_HASH_BITS)
@ -625,6 +628,9 @@ void br_manage_promisc(struct net_bridge *br);
int nbp_backup_change(struct net_bridge_port *p, struct net_device *backup_dev);
/* br_input.c */
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
int br_pass_frame_up(struct sk_buff *skb);
#endif
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
@ -1266,4 +1272,17 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
u16 vid, struct net_bridge_port *p, struct nd_msg *msg);
struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *m);
#ifdef CONFIG_HYFI_BRIDGE_HOOKS
#define __br_get(__hook, __default, __args ...) \
({ typeof(__hook) HOOK_ = (__hook); \
(HOOK_ ? (HOOK_(__args)) : (__default)); })
static inline void __br_notify(int group, int type, const void *data)
{
br_notify_hook_t *notify_hook = rcu_dereference(br_notify_hook);
if (notify_hook)
notify_hook(group, type, data);
}
#endif
#endif