#!/sbin/openrc-run
description="Custom IP Policy Route for Alpine"

depend() {
    need net networking  
    after net-online
    trigger on restart networking  
}

trigger() {
    case "$1" in
        restart)
            ebegin "Triggered by network restart, reloading IP policy rules"
            restart
            eend $?
            ;;
        *)
            ebegin "Unsupported trigger: $1"
            eend 1
            ;;
    esac
}

#空格来分隔不同的前缀
ALL_TUNNEL_SUBNETS="44.32.191.0/24"
BASE_PRIORITY=200
LAN_SUBNET_V4="172.20.0.0/14"
LAN_SUBNET_V6_FD="fd00::/8"
TUNNEL_SUBNET_V6="2000::/3"

add_rules() {
    local current_prio=${BASE_PRIORITY}
    for subnet in ${ALL_TUNNEL_SUBNETS}; do
        ip rule add from ${subnet} lookup 102 priority ${current_prio} 2>/dev/null
        ip rule add to ${subnet} lookup 102 priority $((current_prio + 1)) 2>/dev/null
        current_prio=$((current_prio + 2))
    done

    ip rule add from ${LAN_SUBNET_V4} to ${LAN_SUBNET_V4} lookup 105 priority ${current_prio} 2>/dev/null
    current_prio=$((current_prio + 10))

    ip -6 rule add from ${TUNNEL_SUBNET_V6} to ${TUNNEL_SUBNET_V6} lookup 102 priority ${BASE_PRIORITY} 2>/dev/null
    ip -6 rule add from ${LAN_SUBNET_V6_FD} to ${LAN_SUBNET_V6_FD} lookup 105 priority $((BASE_PRIORITY + 10)) 2>/dev/null
}

del_rules() {
    local current_prio=${BASE_PRIORITY}
    for subnet in ${ALL_TUNNEL_SUBNETS}; do
        ip rule del from ${subnet} lookup 102 priority ${current_prio} 2>/dev/null
        ip rule del to ${subnet} lookup 102 priority $((current_prio + 1)) 2>/dev/null
        current_prio=$((current_prio + 2))
    done

    ip rule del from ${LAN_SUBNET_V4} to ${LAN_SUBNET_V4} lookup 105 priority ${current_prio} 2>/dev/null
    current_prio=$((current_prio + 10))

    ip -6 rule del from ${TUNNEL_SUBNET_V6} to ${TUNNEL_SUBNET_V6} lookup 102 priority ${BASE_PRIORITY} 2>/dev/null
    ip -6 rule del from ${LAN_SUBNET_V6_FD} to ${LAN_SUBNET_V6_FD} lookup 105 priority $((BASE_PRIORITY + 10)) 2>/dev/null
}

start() {
    ebegin "Loading static IP policy rules (tunnel + downstream)"
    add_rules
    eend $? "Failed to load IP policy rules"
}

stop() {
    ebegin "Removing static IP policy rules (tunnel + downstream)"
    del_rules
    eend $? "Failed to remove IP policy rules"
}

restart() {
    stop
    sleep 1
    start
}

reload() {
    ebegin "Refreshing static IP policy rules"
    del_rules
    sleep 0.5
    add_rules
    eend $? "Failed to refresh IP policy rules"
}