external-protocol: rename and update cni-protocol

cni-protocol can be used for both cni and netavark
and also for many other things, such as vpn's that
lack customized protocol supports for openwrt as a
general externally managed protocol, so it was due
to rename it.

I also added one extra option, search domain, which
is optional and updated scripts retrieving ip address
and routing information.

Signed-off-by: Oskari Rauta <oskari.rauta@gmail.com>
This commit is contained in:
Oskari Rauta 2023-11-19 05:19:23 +02:00 committed by Tianling Shen
parent c8d171cf30
commit a0d7e40494
4 changed files with 228 additions and 138 deletions

View File

@ -1,70 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=cni-protocol
PKG_VERSION:=20231008
PKG_RELEASE:=1
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/cni-protocol
SECTION:=net
CATEGORY:=Network
TITLE:=cni netifd protocol
PKGARCH:=all
endef
define Package/cni-protocol/description
protocol support for netavark/cni networks for netifd
makes defining networks for podman and other similar
systems easier and simple.
with protocol, a network where firewall and portmapper
management is disabled, control of firewalling, whether
it was exposing ports, and forwarding to them from wan,
or limiting/accepting access to other networks such
as lan can made through openwrt's own firewalling
configuration.
example configuration could be as following:
- lan network: 10.0.0.0/16 (255.255.0.0)
- container network: 10.129.0.1/24 (255.255.255.0)
Add a network configuration for your container network
using cni protocol. Then create firewall zone for it.
You could create a new container/pod with static ip
address 10.129.0.2 (as 10.129.0.1 as container network's
gateway).
Easily define permissions so that local networks can
connect to cni network, but not the other way around.
Also you want to allow forwarding from/to wan.
Now, as cni cannot access local dns, make a rule for
your firewall to accept connections from cni network
to port 53 (dns).
Now all you have to do, is make redirects to your firewall
and point them to 10.129.0.2 and connections from wan are
redirectered to containers/pods.
Protocol has 2 settings: device and delay. Sometimes polling
interfaces takes some time, and in that case you might want
to add few seconds to delay. Otherwise, it can be excluded
from configuration.
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/cni-protocol/install
$(INSTALL_DIR) $(1)/lib/netifd/proto
$(INSTALL_BIN) ./files/cni.sh $(1)/lib/netifd/proto/cni.sh
endef
$(eval $(call BuildPackage,cni-protocol))

View File

@ -1,68 +0,0 @@
#!/bin/sh
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
}
proto_cni_init_config() {
no_device=0
available=0
proto_config_add_string "device:device"
proto_config_add_int "delay"
}
proto_cni_setup() {
local cfg="$1"
local iface="$2"
local device delay
json_get_vars device delay
[ -n "$device" ] || {
echo "No cni interface specified"
proto_notify_error "$cfg" NO_DEVICE
proto_set_available "$cfg" 0
return 1
}
[ -n "$delay" ] && sleep "$delay"
[ -L "/sys/class/net/${iface}" ] || {
echo "The specified interface $iface is not present"
proto_notify_error "$cfg" NO_DEVICE
proto_set_available "$cfg" 0
return 1
}
local ipaddr netmask broadcast route routemask routesrc
ipaddr=$(ip -4 -o a show "$iface" | awk '{ print $4 }' | cut -d '/' -f1)
netmask=$(ip -4 -o a show "$iface" | awk '{ print $4 }' | cut -d '/' -f2)
broadcast=$(ip -4 -o a show "$iface" | awk '{ print $6 }')
route=$(ip -4 -o r show dev "$iface" | awk '{ print $1 }' | cut -d '/' -f1)
routemask=$(ip -4 -o r show dev "$iface" | awk '{ print $1 }' | cut -d '/' -f2)
routesrc=$(ip -4 -o r show dev "$iface" | awk '{ print $7 }')
[ -z "$ipaddr" ] && {
echo "interface $iface does not have ip address"
proto_notify_error "$cfg" NO_IPADDRESS
return 1
}
proto_init_update "$iface" 1
[ -n "$ipaddr" ] && proto_add_ipv4_address "$ipaddr" "$netmask" "$broadcast" ""
[ -n "$route" ] && proto_add_ipv4_route "$route" "$routemask" "" "$routesrc" ""
proto_send_update "$cfg"
}
proto_cni_teardown() {
local cfg="$1"
return 0
}
[ -n "$INCLUDE_ONLY" ] || {
add_protocol cni
}

View File

@ -0,0 +1,87 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=external-protocol
PKG_VERSION:=20231119
PKG_RELEASE:=1
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
include $(INCLUDE_DIR)/package.mk
define Package/external-protocol
SECTION:=net
CATEGORY:=Network
TITLE:=externally managed protocol
PKGARCH:=all
endef
define Package/external-protocol/description
external protocol is a general protocol for assisting
setup of many virtual devices that lack proper
protocol support in openwrt. Such as netavark, cni and
netbird for example. External protocol is supposed
to be managed with external software, not directly.
external protocol works automaticly on the background
and sets up netifd details when interface comes up or
goes down. This allows one to easily add interface to
a firewall zone.
as a example use case, podman, with network where it's
internal firewall and portmapper are disabled, control
of firewalling, whether it was exposing ports or
limiting/accepting access between networks, such as
lan can be made through openwrt's own firewalling
configuration if you used external protocol.
podman example configuration could be as following:
- lan network: 10.0.0.0/16 (255.255.0.0)
- container network: 10.129.0.1/24 (255.255.255.0)
Add a network configuration for your container network
using external protocol. Then create firewall zone for it.
You could create a new container/pod with static ip
address 10.129.0.2 (as 10.129.0.1 as container network's
gateway).
Easily define permissions so that local networks can
connect to container network, but not the other way around.
Also you want to allow forwarding from/to wan.
Now, as container cannot access local dns, make a rule for
your firewall to accept connections from container network
to port 53 (dns).
Now all you have to do, is make redirects to your firewall
and point them to 10.129.0.2 and connections from wan are
redirectered to containers/pods.
external protocol also works for other applications as
well that are using veth/tun/etc devices and don't have
a hand-tailored protocol available, such as vpn service
netbird.
Protocol has 3 settings: device, searchdomain and delay.
Sometimes polling interfaces takes some time, and in
that case you might want to add few seconds to delay.
Otherwise, it can be excluded from configuration.
Option for searchdomain is also completely optional.
package was previously known as cni protocol but as
it can be used on so many other things, naming became
mis-leading and it was renamed to external protocol.
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/external-protocol/install
$(INSTALL_DIR) $(1)/lib/netifd/proto
$(INSTALL_BIN) ./files/external.sh $(1)/lib/netifd/proto/external.sh
endef
$(eval $(call BuildPackage,external-protocol))

View File

@ -0,0 +1,141 @@
#!/bin/sh
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
}
proto_external_init_config() {
no_device=0
available=0
proto_config_add_string "device:device"
proto_config_add_string "searchdomain"
proto_config_add_int "delay"
}
proto_external_setup() {
local cfg="$1"
local iface="$2"
local device searchdomain delay
json_get_vars device searchdomain delay
[ -n "$device" ] || {
echo "External protocol interface is not specified"
proto_notify_error "$cfg" NO_DEVICE
proto_set_available "$cfg" 0
return 1
}
[ -n "$delay" ] && sleep "$delay"
[ -L "/sys/class/net/${iface}" ] || {
echo "External protocol interface $iface is not present"
proto_notify_error "$cfg" NO_DEVICE
proto_set_available "$cfg" 0
return 1
}
IP4ADDRS=
IP6ADDRS=
local addresses="$(ip -json address list dev "$iface")"
json_init
json_load "{\"addresses\":${addresses}}"
if json_is_a addresses array; then
json_select addresses
json_select 1
if json_is_a addr_info array; then
json_select addr_info
local i=1
while json_is_a ${i} object; do
json_select ${i}
json_get_vars scope family local prefixlen broadcast
if [ "${scope}" == "global" ]; then
case "${family}" in
inet)
append IP4ADDRS "$local/$prefixlen/$broadcast/"
;;
inet6)
append IP6ADDRS "$local/$prefixlen/$broadcast///"
;;
esac
fi
json_select ..
i=$(( i + 1 ))
done
fi
fi
IP4ROUTES=
IP6ROUTES=
local routes="$(ip -json route list dev "$iface")"
json_init
json_load "{\"routes\":${routes}}"
if json_is_a routes array;then
json_select routes
local i=1
while json_is_a ${i} object; do
json_select ${i}
json_get_vars dst gateway metric prefsrc
case "${dst}" in
*:*/*)
append IP6ROUTES "$dst/$gateway/$metric///$prefsrc"
;;
*.*/*)
append IP4ROUTES "$dst/$gateway/$metric///$prefsrc"
;;
*:*)
append IP6ROUTES "$dst/128/$gateway/$metric///$prefsrc"
;;
*.*)
append IP4ROUTES "$dst/32/$gateway/$metric///$prefsrc"
;;
esac
json_select ..
i=$(( i + 1 ))
done
fi
[ -z "${IP4ADDRS}" -a -z "${IP6ADDRS}" ] && {
echo "interface $iface does not have ip address"
proto_notify_error "$cfg" NO_IPADDRESS
return 1
}
proto_init_update "$iface" 1
PROTO_IPADDR="${IP4ADDRS}"
PROTO_IP6ADDR="${IP6ADDRS}"
PROTO_ROUTE="${IP4ROUTES}"
PROTO_ROUTE6="${IP6ROUTES}"
[ -n "$searchdomain" ] && proto_add_dns_search "$searchdomain"
echo "$iface is up"
proto_send_update "$cfg"
}
proto_external_teardown() {
local cfg="$1"
return 0
}
[ -n "$INCLUDE_ONLY" ] || {
add_protocol external
}