mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
shortcut-fe: fix the issue of shortcut-fe-cm. (#7893)
* (TEST) fix the issue of shortcut-fe-cm premature loading * shortcut-fe: bug fixes: a problem of lookup routes when skb provided.
This commit is contained in:
parent
69b0f1cf68
commit
ac6b0edd8d
@ -31,6 +31,7 @@ define KernelPackage/shortcut-fe
|
||||
CONFIG_SHORTCUT_FE=y \
|
||||
CONFIG_XFRM=y
|
||||
PROVIDES:=$(PKG_NAME)
|
||||
AUTOLOAD:=$(call AutoLoad,09,shortcut-fe shortcut-fe-ipv6)
|
||||
endef
|
||||
|
||||
define KernelPackage/shortcut-fe/Description
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#SFE connection manager has a lower priority, it should be started after other connection manager
|
||||
#to detect the existence of connection manager with higher priority
|
||||
START=72
|
||||
START=99
|
||||
|
||||
have_cm() {
|
||||
[ -d "/sys/kernel/debug/ecm" ] && echo 1 && return
|
||||
|
@ -199,7 +199,7 @@ int sfe_cm_recv(struct sk_buff *skb)
|
||||
* structure, obtain the hardware address. This means this function also
|
||||
* works if the neighbours are routers too.
|
||||
*/
|
||||
static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, int is_v4)
|
||||
static bool sfe_cm_find_dev_and_mac_addr(struct sk_buff *skb, sfe_ip_addr_t *addr, struct net_device **dev, u8 *mac_addr, int is_v4)
|
||||
{
|
||||
struct neighbour *neigh;
|
||||
struct rtable *rt;
|
||||
@ -207,6 +207,15 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device
|
||||
struct dst_entry *dst;
|
||||
struct net_device *mac_dev;
|
||||
|
||||
/*
|
||||
* If we have skb provided, use it as the original code is unable
|
||||
* to lookup routes that are policy routed.
|
||||
*/
|
||||
if (unlikely(skb)) {
|
||||
dst = skb_dst(skb);
|
||||
goto skip_dst_lookup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the rtable entry for the IP address then get the hardware
|
||||
* address from its neighbour structure. This means this work when the
|
||||
@ -232,18 +241,21 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device
|
||||
dst = (struct dst_entry *)rt6;
|
||||
}
|
||||
|
||||
skip_dst_lookup:
|
||||
rcu_read_lock();
|
||||
neigh = sfe_dst_get_neighbour(dst, addr);
|
||||
if (unlikely(!neigh)) {
|
||||
rcu_read_unlock();
|
||||
dst_release(dst);
|
||||
if (likely(!skb))
|
||||
dst_release(dst);
|
||||
goto ret_fail;
|
||||
}
|
||||
|
||||
if (unlikely(!(neigh->nud_state & NUD_VALID))) {
|
||||
rcu_read_unlock();
|
||||
neigh_release(neigh);
|
||||
dst_release(dst);
|
||||
if (likely(!skb))
|
||||
dst_release(dst);
|
||||
goto ret_fail;
|
||||
}
|
||||
|
||||
@ -251,7 +263,8 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device
|
||||
if (!mac_dev) {
|
||||
rcu_read_unlock();
|
||||
neigh_release(neigh);
|
||||
dst_release(dst);
|
||||
if (likely(!skb))
|
||||
dst_release(dst);
|
||||
goto ret_fail;
|
||||
}
|
||||
|
||||
@ -261,7 +274,8 @@ static bool sfe_cm_find_dev_and_mac_addr(sfe_ip_addr_t *addr, struct net_device
|
||||
*dev = mac_dev;
|
||||
rcu_read_unlock();
|
||||
neigh_release(neigh);
|
||||
dst_release(dst);
|
||||
if (likely(!skb))
|
||||
dst_release(dst);
|
||||
|
||||
return true;
|
||||
|
||||
@ -291,6 +305,7 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4)
|
||||
struct net_device *dest_dev;
|
||||
struct net_device *src_dev_tmp;
|
||||
struct net_device *dest_dev_tmp;
|
||||
struct sk_buff *tmp_skb = NULL;
|
||||
struct net_device *src_br_dev = NULL;
|
||||
struct net_device *dest_br_dev = NULL;
|
||||
struct nf_conntrack_tuple orig_tuple;
|
||||
@ -581,25 +596,27 @@ static unsigned int sfe_cm_post_routing(struct sk_buff *skb, int is_v4)
|
||||
* Get the net device and MAC addresses that correspond to the various source and
|
||||
* destination host addresses.
|
||||
*/
|
||||
if (!sfe_cm_find_dev_and_mac_addr(&sic.src_ip, &src_dev_tmp, sic.src_mac, is_v4)) {
|
||||
if (!sfe_cm_find_dev_and_mac_addr(NULL, &sic.src_ip, &src_dev_tmp, sic.src_mac, is_v4)) {
|
||||
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_SRC_DEV);
|
||||
return NF_ACCEPT;
|
||||
}
|
||||
src_dev = src_dev_tmp;
|
||||
|
||||
if (!sfe_cm_find_dev_and_mac_addr(&sic.src_ip_xlate, &dev, sic.src_mac_xlate, is_v4)) {
|
||||
if (!sfe_cm_find_dev_and_mac_addr(NULL, &sic.src_ip_xlate, &dev, sic.src_mac_xlate, is_v4)) {
|
||||
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_SRC_XLATE_DEV);
|
||||
goto done1;
|
||||
}
|
||||
dev_put(dev);
|
||||
|
||||
if (!sfe_cm_find_dev_and_mac_addr(&sic.dest_ip, &dev, sic.dest_mac, is_v4)) {
|
||||
/* Somehow, for IPv6, we need this workaround as well */
|
||||
if (unlikely(!is_v4))
|
||||
tmp_skb = skb;
|
||||
if (!sfe_cm_find_dev_and_mac_addr(tmp_skb, &sic.dest_ip, &dev, sic.dest_mac, is_v4)) {
|
||||
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_DEST_DEV);
|
||||
goto done1;
|
||||
}
|
||||
dev_put(dev);
|
||||
|
||||
if (!sfe_cm_find_dev_and_mac_addr(&sic.dest_ip_xlate, &dest_dev_tmp, sic.dest_mac_xlate, is_v4)) {
|
||||
if (!sfe_cm_find_dev_and_mac_addr(skb, &sic.dest_ip_xlate, &dest_dev_tmp, sic.dest_mac_xlate, is_v4)) {
|
||||
sfe_cm_incr_exceptions(SFE_CM_EXCEPTION_NO_DEST_XLATE_DEV);
|
||||
goto done1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user