Initial commit
This commit is contained in:
62
package/network/config/firewall/Makefile
Normal file
62
package/network/config/firewall/Makefile
Normal file
@@ -0,0 +1,62 @@
|
||||
#
|
||||
# Copyright (C) 2013-2016 OpenWrt.org
|
||||
# Copyright (C) 2016 LEDE project
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=firewall
|
||||
PKG_RELEASE:=3
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/firewall3.git
|
||||
PKG_SOURCE_DATE:=2018-08-13
|
||||
PKG_SOURCE_VERSION:=1c4d5bcd1137e61e91dca858fe33d76d7a1dc821
|
||||
PKG_MIRROR_HASH:=49f939877a734056455556c90b959c407fd2c4988dc5d86f62a8122ebd7b8899
|
||||
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||
PKG_LICENSE:=ISC
|
||||
|
||||
PKG_CONFIG_DEPENDS := CONFIG_IPV6
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/firewall
|
||||
SECTION:=net
|
||||
CATEGORY:=Base system
|
||||
TITLE:=OpenWrt C Firewall
|
||||
DEPENDS:=+libubox +libubus +libuci +libip4tc +IPV6:libip6tc +libxtables +kmod-ipt-core +kmod-ipt-conntrack +IPV6:kmod-nf-conntrack6 +kmod-ipt-nat
|
||||
endef
|
||||
|
||||
define Package/firewall/description
|
||||
This package provides a config-compatible C implementation of the UCI firewall.
|
||||
endef
|
||||
|
||||
define Package/firewall/conffiles
|
||||
/etc/config/firewall
|
||||
/etc/firewall.user
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
|
||||
TARGET_LDFLAGS += -Wl,--gc-sections -flto
|
||||
CMAKE_OPTIONS += $(if $(CONFIG_IPV6),,-DDISABLE_IPV6=1)
|
||||
|
||||
define Package/firewall/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/firewall3 $(1)/sbin/fw3
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/firewall.init $(1)/etc/init.d/firewall
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_DATA) ./files/firewall.hotplug $(1)/etc/hotplug.d/iface/20-firewall
|
||||
$(INSTALL_DIR) $(1)/etc/config/
|
||||
$(INSTALL_DATA) ./files/firewall.config $(1)/etc/config/firewall
|
||||
$(INSTALL_DIR) $(1)/etc/
|
||||
$(INSTALL_DATA) ./files/firewall.user $(1)/etc/firewall.user
|
||||
$(INSTALL_DIR) $(1)/usr/share/fw3
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/helpers.conf $(1)/usr/share/fw3
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,firewall))
|
||||
195
package/network/config/firewall/files/firewall.config
Normal file
195
package/network/config/firewall/files/firewall.config
Normal file
@@ -0,0 +1,195 @@
|
||||
config defaults
|
||||
option syn_flood 1
|
||||
option input ACCEPT
|
||||
option output ACCEPT
|
||||
option forward REJECT
|
||||
# Uncomment this line to disable ipv6 rules
|
||||
# option disable_ipv6 1
|
||||
|
||||
config zone
|
||||
option name lan
|
||||
list network 'lan'
|
||||
option input ACCEPT
|
||||
option output ACCEPT
|
||||
option forward ACCEPT
|
||||
|
||||
config zone
|
||||
option name wan
|
||||
list network 'wan'
|
||||
list network 'wan6'
|
||||
option input REJECT
|
||||
option output ACCEPT
|
||||
option forward REJECT
|
||||
option masq 1
|
||||
option mtu_fix 1
|
||||
|
||||
config forwarding
|
||||
option src lan
|
||||
option dest wan
|
||||
|
||||
# We need to accept udp packets on port 68,
|
||||
# see https://dev.openwrt.org/ticket/4108
|
||||
config rule
|
||||
option name Allow-DHCP-Renew
|
||||
option src wan
|
||||
option proto udp
|
||||
option dest_port 68
|
||||
option target ACCEPT
|
||||
option family ipv4
|
||||
|
||||
# Allow IPv4 ping
|
||||
config rule
|
||||
option name Allow-Ping
|
||||
option src wan
|
||||
option proto icmp
|
||||
option icmp_type echo-request
|
||||
option family ipv4
|
||||
option target ACCEPT
|
||||
|
||||
config rule
|
||||
option name Allow-IGMP
|
||||
option src wan
|
||||
option proto igmp
|
||||
option family ipv4
|
||||
option target ACCEPT
|
||||
|
||||
# Allow DHCPv6 replies
|
||||
# see https://dev.openwrt.org/ticket/10381
|
||||
config rule
|
||||
option name Allow-DHCPv6
|
||||
option src wan
|
||||
option proto udp
|
||||
option src_ip fc00::/6
|
||||
option dest_ip fc00::/6
|
||||
option dest_port 546
|
||||
option family ipv6
|
||||
option target ACCEPT
|
||||
|
||||
config rule
|
||||
option name Allow-MLD
|
||||
option src wan
|
||||
option proto icmp
|
||||
option src_ip fe80::/10
|
||||
list icmp_type '130/0'
|
||||
list icmp_type '131/0'
|
||||
list icmp_type '132/0'
|
||||
list icmp_type '143/0'
|
||||
option family ipv6
|
||||
option target ACCEPT
|
||||
|
||||
# Allow essential incoming IPv6 ICMP traffic
|
||||
config rule
|
||||
option name Allow-ICMPv6-Input
|
||||
option src wan
|
||||
option proto icmp
|
||||
list icmp_type echo-request
|
||||
list icmp_type echo-reply
|
||||
list icmp_type destination-unreachable
|
||||
list icmp_type packet-too-big
|
||||
list icmp_type time-exceeded
|
||||
list icmp_type bad-header
|
||||
list icmp_type unknown-header-type
|
||||
list icmp_type router-solicitation
|
||||
list icmp_type neighbour-solicitation
|
||||
list icmp_type router-advertisement
|
||||
list icmp_type neighbour-advertisement
|
||||
option limit 1000/sec
|
||||
option family ipv6
|
||||
option target ACCEPT
|
||||
|
||||
# Allow essential forwarded IPv6 ICMP traffic
|
||||
config rule
|
||||
option name Allow-ICMPv6-Forward
|
||||
option src wan
|
||||
option dest *
|
||||
option proto icmp
|
||||
list icmp_type echo-request
|
||||
list icmp_type echo-reply
|
||||
list icmp_type destination-unreachable
|
||||
list icmp_type packet-too-big
|
||||
list icmp_type time-exceeded
|
||||
list icmp_type bad-header
|
||||
list icmp_type unknown-header-type
|
||||
option limit 1000/sec
|
||||
option family ipv6
|
||||
option target ACCEPT
|
||||
|
||||
config rule
|
||||
option name Allow-IPSec-ESP
|
||||
option src wan
|
||||
option dest lan
|
||||
option proto esp
|
||||
option target ACCEPT
|
||||
|
||||
config rule
|
||||
option name Allow-ISAKMP
|
||||
option src wan
|
||||
option dest lan
|
||||
option dest_port 500
|
||||
option proto udp
|
||||
option target ACCEPT
|
||||
|
||||
# include a file with users custom iptables rules
|
||||
config include
|
||||
option path /etc/firewall.user
|
||||
|
||||
|
||||
### EXAMPLE CONFIG SECTIONS
|
||||
# do not allow a specific ip to access wan
|
||||
#config rule
|
||||
# option src lan
|
||||
# option src_ip 192.168.45.2
|
||||
# option dest wan
|
||||
# option proto tcp
|
||||
# option target REJECT
|
||||
|
||||
# block a specific mac on wan
|
||||
#config rule
|
||||
# option dest wan
|
||||
# option src_mac 00:11:22:33:44:66
|
||||
# option target REJECT
|
||||
|
||||
# block incoming ICMP traffic on a zone
|
||||
#config rule
|
||||
# option src lan
|
||||
# option proto ICMP
|
||||
# option target DROP
|
||||
|
||||
# port redirect port coming in on wan to lan
|
||||
#config redirect
|
||||
# option src wan
|
||||
# option src_dport 80
|
||||
# option dest lan
|
||||
# option dest_ip 192.168.16.235
|
||||
# option dest_port 80
|
||||
# option proto tcp
|
||||
|
||||
# port redirect of remapped ssh port (22001) on wan
|
||||
#config redirect
|
||||
# option src wan
|
||||
# option src_dport 22001
|
||||
# option dest lan
|
||||
# option dest_port 22
|
||||
# option proto tcp
|
||||
|
||||
### FULL CONFIG SECTIONS
|
||||
#config rule
|
||||
# option src lan
|
||||
# option src_ip 192.168.45.2
|
||||
# option src_mac 00:11:22:33:44:55
|
||||
# option src_port 80
|
||||
# option dest wan
|
||||
# option dest_ip 194.25.2.129
|
||||
# option dest_port 120
|
||||
# option proto tcp
|
||||
# option target REJECT
|
||||
|
||||
#config redirect
|
||||
# option src lan
|
||||
# option src_ip 192.168.45.2
|
||||
# option src_mac 00:11:22:33:44:55
|
||||
# option src_port 1024
|
||||
# option src_dport 80
|
||||
# option dest_ip 194.25.2.129
|
||||
# option dest_port 120
|
||||
# option proto tcp
|
||||
11
package/network/config/firewall/files/firewall.hotplug
Normal file
11
package/network/config/firewall/files/firewall.hotplug
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$ACTION" = ifup -o "$ACTION" = ifupdate ] || exit 0
|
||||
[ "$ACTION" = ifupdate -a -z "$IFUPDATE_ADDRESSES" -a -z "$IFUPDATE_DATA" ] && exit 0
|
||||
|
||||
/etc/init.d/firewall enabled || exit 0
|
||||
|
||||
fw3 -q network "$INTERFACE" >/dev/null || exit 0
|
||||
|
||||
logger -t firewall "Reloading firewall due to $ACTION of $INTERFACE ($DEVICE)"
|
||||
fw3 -q reload
|
||||
61
package/network/config/firewall/files/firewall.init
Executable file
61
package/network/config/firewall/files/firewall.init
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=19
|
||||
USE_PROCD=1
|
||||
QUIET=""
|
||||
|
||||
validate_firewall_redirect()
|
||||
{
|
||||
uci_validate_section firewall redirect "${1}" \
|
||||
'proto:or(uinteger, string)' \
|
||||
'src:string' \
|
||||
'src_ip:cidr' \
|
||||
'src_dport:or(port, portrange)' \
|
||||
'dest:string' \
|
||||
'dest_ip:cidr' \
|
||||
'dest_port:or(port, portrange)' \
|
||||
'target:or("SNAT", "DNAT")'
|
||||
}
|
||||
|
||||
validate_firewall_rule()
|
||||
{
|
||||
uci_validate_section firewall rule "${1}" \
|
||||
'proto:or(uinteger, string)' \
|
||||
'src:string' \
|
||||
'dest:string' \
|
||||
'src_port:or(port, portrange)' \
|
||||
'dest_port:or(port, portrange)' \
|
||||
'target:string'
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger firewall
|
||||
|
||||
procd_open_validate
|
||||
validate_firewall_redirect
|
||||
validate_firewall_rule
|
||||
procd_close_validate
|
||||
}
|
||||
|
||||
restart() {
|
||||
fw3 restart
|
||||
}
|
||||
|
||||
start_service() {
|
||||
fw3 ${QUIET} start
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
fw3 flush
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
fw3 reload
|
||||
}
|
||||
|
||||
boot() {
|
||||
# Be silent on boot, firewall might be started by hotplug already,
|
||||
# so don't complain in syslog.
|
||||
QUIET=-q
|
||||
start
|
||||
}
|
||||
7
package/network/config/firewall/files/firewall.user
Normal file
7
package/network/config/firewall/files/firewall.user
Normal file
@@ -0,0 +1,7 @@
|
||||
# This file is interpreted as shell script.
|
||||
# Put your custom iptables rules here, they will
|
||||
# be executed with each firewall (re-)start.
|
||||
|
||||
# Internal uci firewall chains are flushed and recreated on reload, so
|
||||
# put custom rules into the root chains e.g. INPUT or FORWARD or into the
|
||||
# special user chains, e.g. input_wan_rule or postrouting_lan_rule.
|
||||
@@ -0,0 +1,33 @@
|
||||
From c9f48cb3bd0e14fec8ad71c3baef7c280a390b4f Mon Sep 17 00:00:00 2001
|
||||
From: Yousong Zhou <yszhou4tech@gmail.com>
|
||||
Date: Fri, 24 Jul 2020 12:52:59 +0800
|
||||
Subject: [PATCH] zones: apply tcp mss clamping also on ingress path
|
||||
|
||||
Fixes FS#3231
|
||||
|
||||
Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
|
||||
Acked-by: Jo-Philipp Wich <jo@mein.io>
|
||||
(cherry picked from commit e9b90dfac2225927c035f6a76277b850c282dc9a)
|
||||
---
|
||||
zones.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/zones.c b/zones.c
|
||||
index 505ab20..4656f88 100644
|
||||
--- a/zones.c
|
||||
+++ b/zones.c
|
||||
@@ -553,6 +553,14 @@ print_interface_rule(struct fw3_ipt_handle *handle, struct fw3_state *state,
|
||||
fw3_ipt_rule_target(r, "TCPMSS");
|
||||
fw3_ipt_rule_addarg(r, false, "--clamp-mss-to-pmtu", NULL);
|
||||
fw3_ipt_rule_replace(r, "FORWARD");
|
||||
+
|
||||
+ r = fw3_ipt_rule_create(handle, &tcp, dev, NULL, sub, NULL);
|
||||
+ fw3_ipt_rule_addarg(r, false, "--tcp-flags", "SYN,RST");
|
||||
+ fw3_ipt_rule_addarg(r, false, "SYN", NULL);
|
||||
+ fw3_ipt_rule_comment(r, "Zone %s MTU fixing", zone->name);
|
||||
+ fw3_ipt_rule_target(r, "TCPMSS");
|
||||
+ fw3_ipt_rule_addarg(r, false, "--clamp-mss-to-pmtu", NULL);
|
||||
+ fw3_ipt_rule_replace(r, "FORWARD");
|
||||
}
|
||||
}
|
||||
else if (handle->table == FW3_TABLE_RAW)
|
||||
@@ -0,0 +1,38 @@
|
||||
From 78d52a28c66ad0fd2af250038fdcf4239ad37bf2 Mon Sep 17 00:00:00 2001
|
||||
From: Remi NGUYEN VAN <remi.nguyenvan+openwrt@gmail.com>
|
||||
Date: Sat, 15 Aug 2020 13:50:27 +0900
|
||||
Subject: [PATCH] options: fix parsing of boolean attributes
|
||||
|
||||
Boolean attributes were parsed the same way as string attributes,
|
||||
so a value of { "bool_attr": "true" } would be parsed correctly, but
|
||||
{ "bool_attr": true } (without quotes) was parsed as false.
|
||||
|
||||
Fixes FS#3284
|
||||
|
||||
Signed-off-by: Remi NGUYEN VAN <remi.nguyenvan+openwrt@gmail.com>
|
||||
---
|
||||
options.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
--- a/options.c
|
||||
+++ b/options.c
|
||||
@@ -1170,6 +1170,9 @@ fw3_parse_blob_options(void *s, const st
|
||||
if (blobmsg_type(e) == BLOBMSG_TYPE_INT32) {
|
||||
snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(e));
|
||||
v = buf;
|
||||
+ } else if (blobmsg_type(o) == BLOBMSG_TYPE_BOOL) {
|
||||
+ snprintf(buf, sizeof(buf), "%d", blobmsg_get_bool(o));
|
||||
+ v = buf;
|
||||
} else {
|
||||
v = blobmsg_get_string(e);
|
||||
}
|
||||
@@ -1189,6 +1192,9 @@ fw3_parse_blob_options(void *s, const st
|
||||
if (blobmsg_type(o) == BLOBMSG_TYPE_INT32) {
|
||||
snprintf(buf, sizeof(buf), "%d", blobmsg_get_u32(o));
|
||||
v = buf;
|
||||
+ } else if (blobmsg_type(o) == BLOBMSG_TYPE_BOOL) {
|
||||
+ snprintf(buf, sizeof(buf), "%d", blobmsg_get_bool(o));
|
||||
+ v = buf;
|
||||
} else {
|
||||
v = blobmsg_get_string(o);
|
||||
}
|
||||
44
package/network/config/gre/Makefile
Normal file
44
package/network/config/gre/Makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
#
|
||||
# Copyright (C) 2014 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gre
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=9
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/gre/Default
|
||||
endef
|
||||
|
||||
define Package/gre
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
|
||||
TITLE:=Generic Routing Encapsulation config support
|
||||
DEPENDS:=+kmod-gre +IPV6:kmod-gre6 +resolveip
|
||||
PROVIDES:=grev4 grev6
|
||||
endef
|
||||
|
||||
define Package/gre/description
|
||||
Generic Routing Encapsulation config support (IPv4 and IPv6) in /etc/config/network.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/gre/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/gre.sh $(1)/lib/netifd/proto/gre.sh
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,gre))
|
||||
291
package/network/config/gre/files/gre.sh
Executable file
291
package/network/config/gre/files/gre.sh
Executable file
@@ -0,0 +1,291 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
gre_generic_setup() {
|
||||
local cfg="$1"
|
||||
local mode="$2"
|
||||
local local="$3"
|
||||
local remote="$4"
|
||||
local link="$5"
|
||||
local mtu ttl tos zone ikey okey icsum ocsum iseqno oseqno multicast
|
||||
json_get_vars mtu ttl tos zone ikey okey icsum ocsum iseqno oseqno multicast
|
||||
|
||||
[ -z "$zone" ] && zone="wan"
|
||||
[ -z "$multicast" ] && multicast=1
|
||||
|
||||
proto_init_update "$link" 1
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode "$mode"
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
[ -n "$df" ] && json_add_boolean df "$df"
|
||||
[ -n "$ttl" ] && json_add_int ttl "$ttl"
|
||||
[ -n "$tos" ] && json_add_string tos "$tos"
|
||||
json_add_boolean multicast "$multicast"
|
||||
json_add_string local "$local"
|
||||
json_add_string remote "$remote"
|
||||
[ -n "$tunlink" ] && json_add_string link "$tunlink"
|
||||
|
||||
json_add_object 'data'
|
||||
[ -n "$ikey" ] && json_add_int ikey "$ikey"
|
||||
[ -n "$okey" ] && json_add_int okey "$okey"
|
||||
[ -n "$icsum" ] && json_add_boolean icsum "$icsum"
|
||||
[ -n "$ocsum" ] && json_add_boolean ocsum "$ocsum"
|
||||
[ -n "$iseqno" ] && json_add_boolean iseqno "$iseqno"
|
||||
[ -n "$oseqno" ] && json_add_boolean oseqno "$oseqno"
|
||||
[ -n "$encaplimit" ] && json_add_string encaplimit "$encaplimit"
|
||||
json_close_object
|
||||
|
||||
proto_close_tunnel
|
||||
|
||||
proto_add_data
|
||||
[ -n "$zone" ] && json_add_string zone "$zone"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$cfg"
|
||||
}
|
||||
|
||||
gre_setup() {
|
||||
local cfg="$1"
|
||||
local mode="$2"
|
||||
local remoteip
|
||||
|
||||
local ipaddr peeraddr
|
||||
json_get_vars df ipaddr peeraddr tunlink
|
||||
|
||||
[ -z "$peeraddr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_PEER_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
exit
|
||||
}
|
||||
|
||||
remoteip=$(resolveip -t 10 -4 "$peeraddr")
|
||||
|
||||
if [ -z "$remoteip" ]; then
|
||||
proto_notify_error "$cfg" "PEER_RESOLVE_FAIL"
|
||||
exit
|
||||
fi
|
||||
|
||||
for ip in $remoteip; do
|
||||
peeraddr=$ip
|
||||
break
|
||||
done
|
||||
|
||||
( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
|
||||
|
||||
[ -z "$ipaddr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z $wanif ] && ! network_find_wan wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr ipaddr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
[ -z "$df" ] && df="1"
|
||||
|
||||
case "$mode" in
|
||||
gretapip)
|
||||
gre_generic_setup $cfg $mode $ipaddr $peeraddr "gre4t-$cfg"
|
||||
;;
|
||||
*)
|
||||
gre_generic_setup $cfg $mode $ipaddr $peeraddr "gre4-$cfg"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
proto_gre_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
gre_setup $cfg "greip"
|
||||
}
|
||||
|
||||
proto_gretap_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
local network
|
||||
json_get_vars network
|
||||
|
||||
gre_setup $cfg "gretapip"
|
||||
|
||||
json_init
|
||||
json_add_string name "gre4t-$cfg"
|
||||
json_add_boolean link-ext 0
|
||||
json_close_object
|
||||
|
||||
for i in $network; do
|
||||
ubus call network.interface."$i" add_device "$(json_dump)"
|
||||
done
|
||||
}
|
||||
|
||||
grev6_setup() {
|
||||
local cfg="$1"
|
||||
local mode="$2"
|
||||
local remoteip6
|
||||
|
||||
local ip6addr peer6addr weakif
|
||||
json_get_vars ip6addr peer6addr tunlink weakif encaplimit
|
||||
|
||||
[ -z "$peer6addr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_PEER_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
exit
|
||||
}
|
||||
|
||||
remoteip6=$(resolveip -t 10 -6 "$peer6addr")
|
||||
|
||||
if [ -z "$remoteip6" ]; then
|
||||
proto_notify_error "$cfg" "PEER_RESOLVE_FAIL"
|
||||
exit
|
||||
fi
|
||||
|
||||
for ip6 in $remoteip6; do
|
||||
peer6addr=$ip6
|
||||
break
|
||||
done
|
||||
|
||||
( proto_add_host_dependency "$cfg" "$peer6addr" "$tunlink" )
|
||||
|
||||
[ -z "$ip6addr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z $wanif ] && ! network_find_wan6 wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr6 ip6addr "$wanif"; then
|
||||
[ -z "$weakif" ] && weakif="lan"
|
||||
if ! network_get_ipaddr6 ip6addr "$weakif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
case "$mode" in
|
||||
gretapip6)
|
||||
gre_generic_setup $cfg $mode $ip6addr $peer6addr "gre6t-$cfg"
|
||||
;;
|
||||
*)
|
||||
gre_generic_setup $cfg $mode $ip6addr $peer6addr "gre6-$cfg"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
proto_grev6_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
grev6_setup $cfg "greip6"
|
||||
}
|
||||
|
||||
proto_grev6tap_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
local network
|
||||
json_get_vars network
|
||||
|
||||
grev6_setup $cfg "gretapip6"
|
||||
|
||||
json_init
|
||||
json_add_string name "gre6t-$cfg"
|
||||
json_add_boolean link-ext 0
|
||||
json_close_object
|
||||
|
||||
for i in $network; do
|
||||
ubus call network.interface."$i" add_device "$(json_dump)"
|
||||
done
|
||||
}
|
||||
|
||||
gretap_generic_teardown() {
|
||||
local network
|
||||
json_get_vars network
|
||||
|
||||
json_init
|
||||
json_add_string name "$1"
|
||||
json_add_boolean link-ext 0
|
||||
json_close_object
|
||||
|
||||
for i in $network; do
|
||||
ubus call network.interface."$i" remove_device "$(json_dump)"
|
||||
done
|
||||
}
|
||||
|
||||
proto_gre_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_gretap_teardown() {
|
||||
local cfg="$1"
|
||||
|
||||
gretap_generic_teardown "gre4t-$cfg"
|
||||
}
|
||||
|
||||
proto_grev6_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_grev6tap_teardown() {
|
||||
local cfg="$1"
|
||||
|
||||
gretap_generic_teardown "gre6t-$cfg"
|
||||
}
|
||||
|
||||
gre_generic_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_string "tos"
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_string "zone"
|
||||
proto_config_add_int "ikey"
|
||||
proto_config_add_int "okey"
|
||||
proto_config_add_boolean "icsum"
|
||||
proto_config_add_boolean "ocsum"
|
||||
proto_config_add_boolean "iseqno"
|
||||
proto_config_add_boolean "oseqno"
|
||||
proto_config_add_boolean "multicast"
|
||||
}
|
||||
|
||||
proto_gre_init_config() {
|
||||
gre_generic_init_config
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_string "peeraddr"
|
||||
proto_config_add_boolean "df"
|
||||
}
|
||||
|
||||
proto_gretap_init_config() {
|
||||
proto_gre_init_config
|
||||
proto_config_add_string "network"
|
||||
}
|
||||
|
||||
proto_grev6_init_config() {
|
||||
gre_generic_init_config
|
||||
proto_config_add_string "ip6addr"
|
||||
proto_config_add_string "peer6addr"
|
||||
proto_config_add_string "weakif"
|
||||
proto_config_add_string "encaplimit"
|
||||
}
|
||||
|
||||
proto_grev6tap_init_config() {
|
||||
proto_grev6_init_config
|
||||
proto_config_add_string "network"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
[ -f /lib/modules/$(uname -r)/gre.ko ] && add_protocol gre
|
||||
[ -f /lib/modules/$(uname -r)/gre.ko ] && add_protocol gretap
|
||||
[ -f /lib/modules/$(uname -r)/ip6_gre.ko ] && add_protocol grev6
|
||||
[ -f /lib/modules/$(uname -r)/ip6_gre.ko ] && add_protocol grev6tap
|
||||
}
|
||||
40
package/network/config/ipip/Makefile
Normal file
40
package/network/config/ipip/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (C) 2014 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ipip
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=2
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ipip
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
|
||||
TITLE:=IP in IP Tunnel config support
|
||||
DEPENDS:= +kmod-ipip +resolveip
|
||||
endef
|
||||
|
||||
define Package/ipip/description
|
||||
IP in IP Tunnel config support in /etc/config/network.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/ipip/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/ipip.sh $(1)/lib/netifd/proto/ipip.sh
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ipip))
|
||||
93
package/network/config/ipip/files/ipip.sh
Executable file
93
package/network/config/ipip/files/ipip.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
proto_ipip_setup() {
|
||||
local cfg="$1"
|
||||
local remoteip
|
||||
|
||||
local df ipaddr peeraddr tunlink ttl tos zone mtu
|
||||
json_get_vars df ipaddr peeraddr tunlink ttl tos zone mtu
|
||||
|
||||
[ -z "$peeraddr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_PEER_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
return
|
||||
}
|
||||
|
||||
remoteip=$(resolveip -t 10 -4 "$peeraddr")
|
||||
|
||||
if [ -z "$remoteip" ]; then
|
||||
proto_notify_error "$cfg" "PEER_RESOLVE_FAIL"
|
||||
return
|
||||
fi
|
||||
|
||||
for ip in $remoteip; do
|
||||
peeraddr=$ip
|
||||
break
|
||||
done
|
||||
|
||||
( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
|
||||
|
||||
[ -z "$ipaddr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z $wanif ] && ! network_find_wan wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr ipaddr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
[ -z "$zone" ] && zone="wan"
|
||||
|
||||
proto_init_update "ipip-$cfg" 1
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode "ipip"
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
json_add_int ttl "${ttl:-64}"
|
||||
[ -n "$tos" ] && json_add_string tos "$tos"
|
||||
json_add_string local "$ipaddr"
|
||||
json_add_string remote "$peeraddr"
|
||||
[ -n "$tunlink" ] && json_add_string link "$tunlink"
|
||||
json_add_boolean df "${df:-1}"
|
||||
|
||||
proto_close_tunnel
|
||||
|
||||
proto_add_data
|
||||
[ -n "$zone" ] && json_add_string zone "$zone"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$cfg"
|
||||
}
|
||||
|
||||
proto_ipip_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_ipip_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_string "tos"
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_string "zone"
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_string "peeraddr"
|
||||
proto_config_add_boolean "df"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol ipip
|
||||
}
|
||||
86
package/network/config/ltq-adsl-app/Makefile
Normal file
86
package/network/config/ltq-adsl-app/Makefile
Normal file
@@ -0,0 +1,86 @@
|
||||
#
|
||||
# Copyright (C) 2011-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=dsl_cpe_control_danube
|
||||
PKG_VERSION:=3.24.4.4
|
||||
PKG_RELEASE:=6
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/dsl_cpe_control-$(PKG_VERSION)
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
|
||||
PKG_HASH:=af0bdf45cc7a62e2b38d39aad4924dd83c24fae170ae5bbd8190c2a3d9106257
|
||||
PKG_MAINTAINER:=John Crispin <john@phrozen.org>
|
||||
PKG_LICENSE:=BSD-3-Clause
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
|
||||
PKG_CONFIG_DEPENDS:=\
|
||||
CONFIG_LTQ_DSL_ENABLE_SOAP \
|
||||
CONFIG_LTQ_DSL_ENABLE_DSL_EVENT_POLLING
|
||||
|
||||
PKG_BUILD_DEPENDS:=ltq-adsl
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ltq-adsl-app
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Lantiq DSL userland tool
|
||||
URL:=http://www.lantiq.com/
|
||||
DEPENDS:=@(TARGET_lantiq_xway||TARGET_lantiq_xway_legacy||TARGET_lantiq_ase) +libpthread
|
||||
MENU:=1
|
||||
endef
|
||||
|
||||
define Package/ltq-adsl-app/description
|
||||
Infineon DSL CPE API for Amazon SE, Danube and Vinax.
|
||||
endef
|
||||
|
||||
LTQ_DSL_MAX_DEVICE=1
|
||||
LTQ_DSL_LINES_PER_DEVICE=1
|
||||
LTQ_DSL_CHANNELS_PER_LINE=1
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--with-max-device="$(LTQ_DSL_MAX_DEVICE)" \
|
||||
--with-lines-per-device="$(LTQ_DSL_LINES_PER_DEVICE)" \
|
||||
--with-channels-per-line="$(LTQ_DSL_CHANNELS_PER_LINE)" \
|
||||
--enable-danube \
|
||||
--enable-driver-include="-I$(STAGING_DIR)/usr/include/adsl/" \
|
||||
--enable-debug-prints \
|
||||
--enable-add-appl-cflags="-DMAX_CLI_PIPES=2" \
|
||||
--enable-cli-support \
|
||||
--enable-cmv-scripts \
|
||||
--enable-debug-tool-interface \
|
||||
--enable-adsl-led \
|
||||
--enable-dsl-ceoc \
|
||||
--enable-script-notification \
|
||||
--enable-dsl-pm \
|
||||
--enable-dsl-pm-total \
|
||||
--enable-dsl-pm-history \
|
||||
--enable-dsl-pm-showtime \
|
||||
--enable-dsl-pm-channel-counters \
|
||||
--enable-dsl-pm-datapath-counters \
|
||||
--enable-dsl-pm-line-counters \
|
||||
--enable-dsl-pm-channel-thresholds \
|
||||
--enable-dsl-pm-datapath-thresholds \
|
||||
--enable-dsl-pm-line-thresholds \
|
||||
--enable-dsl-pm-optional-parameters
|
||||
|
||||
TARGET_CFLAGS += -I$(LINUX_DIR)/include
|
||||
|
||||
define Package/ltq-adsl-app/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d $(1)/sbin $(1)/etc/hotplug.d/dsl
|
||||
$(INSTALL_BIN) ./files/dsl_control $(1)/etc/init.d/
|
||||
$(INSTALL_BIN) ./files/10_atm.sh $(1)/etc/hotplug.d/dsl
|
||||
$(INSTALL_BIN) ./files/10_ptm.sh $(1)/etc/hotplug.d/dsl
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ltq-adsl-app))
|
||||
29
package/network/config/ltq-adsl-app/files/10_atm.sh
Executable file
29
package/network/config/ltq-adsl-app/files/10_atm.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$DSL_NOTIFICATION_TYPE" = "DSL_STATUS" ] && \
|
||||
[ "$DSL_TC_LAYER_STATUS" = "ATM" ] && \
|
||||
! grep -q "ltq_atm_ar9\|ltq_atm_ase\|ltq_atm_danube" /proc/modules || exit 0
|
||||
|
||||
logger -p daemon.notice -t "dsl-notify" "Switching to TC-Layer ATM"
|
||||
|
||||
if grep -q "ltq_ptm_ar9\|ltq_ptm_ase\|ltq_ptm_danube" /proc/modules ; then
|
||||
logger -p daemon.notice -t "dsl-notify" "Loading ATM driver while EFM/PTM driver is loaded is not possible. Reboot is needed."
|
||||
exit
|
||||
fi
|
||||
|
||||
case "$(strings /proc/device-tree/compatible)" in
|
||||
*lantiq,ar9*)
|
||||
soc="ar9"
|
||||
;;
|
||||
*lantiq,ase*)
|
||||
soc="ase"
|
||||
;;
|
||||
*lantiq,danube*)
|
||||
soc="danube"
|
||||
;;
|
||||
*)
|
||||
logger -p daemon.notice -t "dsl-notify" "Unsupported SoC"
|
||||
exit
|
||||
esac
|
||||
|
||||
modprobe ltq_atm_${soc}
|
||||
29
package/network/config/ltq-adsl-app/files/10_ptm.sh
Executable file
29
package/network/config/ltq-adsl-app/files/10_ptm.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$DSL_NOTIFICATION_TYPE" = "DSL_STATUS" ] && \
|
||||
[ "$DSL_TC_LAYER_STATUS" = "EFM" ] && \
|
||||
! grep -q "ltq_ptm_ar9\|ltq_ptm_ase\|ltq_ptm_danube" /proc/modules || exit 0
|
||||
|
||||
logger -p daemon.notice -t "dsl-notify" "Switching to TC-Layer EFM/PTM"
|
||||
|
||||
if grep -q "ltq_atm_ar9\|ltq_atm_ase\|ltq_atm_danube" /proc/modules ; then
|
||||
logger -p daemon.notice -t "dsl-notify" "Loading EFM/PTM driver while ATM driver is loaded is not possible. Reboot is needed."
|
||||
exit
|
||||
fi
|
||||
|
||||
case "$(strings /proc/device-tree/compatible)" in
|
||||
*lantiq,ar9*)
|
||||
soc="ar9"
|
||||
;;
|
||||
*lantiq,ase*)
|
||||
soc="ase"
|
||||
;;
|
||||
*lantiq,danube*)
|
||||
soc="danube"
|
||||
;;
|
||||
*)
|
||||
logger -p daemon.notice -t "dsl-notify" "Unsupported SoC"
|
||||
exit
|
||||
esac
|
||||
|
||||
modprobe ltq_ptm_${soc}
|
||||
65
package/network/config/ltq-adsl-app/files/dsl_control
Normal file
65
package/network/config/ltq-adsl-app/files/dsl_control
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2012 OpenWrt.org
|
||||
|
||||
START=97
|
||||
USE_PROCD=1
|
||||
|
||||
EXTRA_COMMANDS="status lucistat"
|
||||
EXTRA_HELP=" status Get DSL status information
|
||||
lucistat Get status information if lua friendly format"
|
||||
|
||||
[ -f /lib/functions/lantiq_dsl.sh ] && . /lib/functions/lantiq_dsl.sh
|
||||
|
||||
annex_b=10_00_10_00_00_04_00_00
|
||||
annex_bdmt=10_00_00_00_00_00_00_00
|
||||
annex_b2=00_00_10_00_00_00_00_00
|
||||
annex_b2p=00_00_00_00_00_04_00_00
|
||||
annex_a=05_01_04_00_4C_01_04_00
|
||||
annex_at1=01_00_00_00_00_00_00_00
|
||||
annex_alite=00_01_00_00_00_00_00_00
|
||||
annex_admt=04_00_00_00_00_00_00_00
|
||||
annex_a2=00_00_04_00_00_00_00_00
|
||||
annex_a2p=00_00_00_00_00_01_00_00
|
||||
annex_l=00_00_00_00_0C_00_00_00
|
||||
annex_m=00_00_00_00_40_00_04_00
|
||||
annex_m2=00_00_00_00_40_00_00_00
|
||||
annex_m2p=00_00_00_00_00_00_04_00
|
||||
annex_j=10_00_10_40_00_04_01_00
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger network
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local annex
|
||||
local firmware
|
||||
local xtu
|
||||
config_load network
|
||||
config_get annex dsl annex
|
||||
config_get firmware dsl firmware
|
||||
|
||||
eval "xtu=\"\${annex_$annex}\""
|
||||
|
||||
[ -z "${firmware}" ] &&
|
||||
firmware=/lib/firmware/adsl.bin
|
||||
[ -f "${firmware}" ] || {
|
||||
echo failed to find $firmware
|
||||
return 1
|
||||
}
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /sbin/dsl_cpe_control \
|
||||
-i${xtu} \
|
||||
-n /sbin/dsl_notify.sh \
|
||||
-f ${firmware}
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
DSL_NOTIFICATION_TYPE="DSL_INTERFACE_STATUS" \
|
||||
DSL_INTERFACE_STATUS="DOWN" \
|
||||
/sbin/dsl_notify.sh
|
||||
|
||||
service_stop /sbin/dsl_cpe_control
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
--- a/src/dsl_cpe_cli_access.c 2016-05-27 12:34:43.612485449 -0700
|
||||
+++ b/src/dsl_cpe_cli_access.c 2016-05-27 12:45:37.491727862 -0700
|
||||
@@ -1142,7 +1142,7 @@
|
||||
|
||||
if ((ret < 0) && (autobootCtrl.accessCtl.nReturn < DSL_SUCCESS))
|
||||
{
|
||||
- DSL_CPE_FPrintf (out, sFailureReturn, autobootCtrl.accessCtl.nReturn);
|
||||
+ DSL_CPE_FPrintf (out, sFailureReturn, autobootCtrl.accessCtl.nReturn, DSL_CPE_Fd2DevStr(fd));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1213,7 +1213,7 @@
|
||||
|
||||
if ((ret < 0) && (pData.accessCtl.nReturn < DSL_SUCCESS))
|
||||
{
|
||||
- DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn);
|
||||
+ DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn, DSL_CPE_Fd2DevStr(fd));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1290,7 +1290,7 @@
|
||||
|
||||
if ((ret < 0) && (pData.accessCtl.nReturn < DSL_SUCCESS))
|
||||
{
|
||||
- DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn);
|
||||
+ DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn, DSL_CPE_Fd2DevStr(fd));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1355,7 +1355,7 @@
|
||||
pCtx, &resourceUsageStatisticsData);
|
||||
if (ret < 0)
|
||||
{
|
||||
- DSL_CPE_FPrintf (out, sFailureReturn, ret);
|
||||
+ DSL_CPE_FPrintf (out, sFailureReturn, ret, DSL_CPE_Fd2DevStr(fd));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3084,7 +3084,7 @@
|
||||
|
||||
if ((ret < 0) && (pData->accessCtl.nReturn < DSL_SUCCESS))
|
||||
{
|
||||
- DSL_CPE_FPrintf (out, sFailureReturn, pData->accessCtl.nReturn);
|
||||
+ DSL_CPE_FPrintf (out, sFailureReturn, pData->accessCtl.nReturn, DSL_CPE_Fd2DevStr(fd));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4654,7 +4654,7 @@
|
||||
|
||||
if ((ret < 0) && (pData.accessCtl.nReturn < DSL_SUCCESS))
|
||||
{
|
||||
- DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn);
|
||||
+ DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn, DSL_CPE_Fd2DevStr(fd));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5714,7 +5714,7 @@
|
||||
|
||||
if ((ret < 0) && (pData.accessCtl.nReturn < DSL_SUCCESS))
|
||||
{
|
||||
- DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn);
|
||||
+ DSL_CPE_FPrintf (out, sFailureReturn, pData.accessCtl.nReturn, DSL_CPE_Fd2DevStr(fd));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -0,0 +1,23 @@
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -29,6 +29,8 @@ AC_C_VOLATILE
|
||||
#AC_FUNC_STRTOD
|
||||
#AC_CHECK_FUNCS([ftime gethostbyname gettimeofday localtime_r memset select socket strchr strerror strstr strtoull])
|
||||
|
||||
+AC_SEARCH_LIBS([clock_gettime],[rt])
|
||||
+
|
||||
#
|
||||
# save the configure arguments
|
||||
#
|
||||
--- a/src/dsl_cpe_linux.h
|
||||
+++ b/src/dsl_cpe_linux.h
|
||||
@@ -45,7 +45,8 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h> /* socket */
|
||||
#include <sys/sem.h> /* semget */
|
||||
-#include <semaphore.h> /* sem_t */
|
||||
+#include <semaphore.h> /* sem_t */
|
||||
+#include <limits.h>
|
||||
|
||||
#ifdef DSL_DEBUG_TOOL_INTERFACE
|
||||
#include <sys/socket.h>
|
||||
@@ -0,0 +1,42 @@
|
||||
From 9d4f86ba2cf10304303011f4f5628fa68dc77624 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Kresin <dev@kresin.me>
|
||||
Date: Mon, 16 Oct 2017 21:08:26 +0200
|
||||
Subject: ltq-adsl-app: add more script notifications
|
||||
|
||||
Backport HANDSHAKE and TRAINING notification from ltq-vdsl-app. It
|
||||
unifies the dsl led blinking pattern accross all subtargets and allows
|
||||
to get the current line status from the dsl led.
|
||||
|
||||
Signed-off-by: Mathias Kresin <dev@kresin.me>
|
||||
---
|
||||
.../100-add-more-script-notifications.patch | 27 ++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
create mode 100644 package/network/config/ltq-adsl-app/patches/100-add-more-script-notifications.patch
|
||||
|
||||
--- a/src/dsl_cpe_control.c
|
||||
+++ b/src/dsl_cpe_control.c
|
||||
@@ -3273,7 +3273,23 @@ DSL_CPE_STATIC DSL_int_t DSL_CPE_Event_S
|
||||
#ifdef INCLUDE_SCRIPT_NOTIFICATION
|
||||
if (g_sRcScript != DSL_NULL)
|
||||
{
|
||||
- if ( (nLineState == DSL_LINESTATE_SHOWTIME_TC_SYNC) &&
|
||||
+ if ( (nLineState == DSL_LINESTATE_HANDSHAKE) &&
|
||||
+ (g_nPrevLineState[nDevice] != DSL_LINESTATE_HANDSHAKE) )
|
||||
+ {
|
||||
+ if (DSL_CPE_SetEnv("DSL_INTERFACE_STATUS", "HANDSHAKE") == DSL_SUCCESS)
|
||||
+ {
|
||||
+ bExec = DSL_TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ else if ( (nLineState == DSL_LINESTATE_FULL_INIT) &&
|
||||
+ (g_nPrevLineState[nDevice] != DSL_LINESTATE_FULL_INIT) )
|
||||
+ {
|
||||
+ if (DSL_CPE_SetEnv("DSL_INTERFACE_STATUS", "TRAINING") == DSL_SUCCESS)
|
||||
+ {
|
||||
+ bExec = DSL_TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+ else if ( (nLineState == DSL_LINESTATE_SHOWTIME_TC_SYNC) &&
|
||||
(g_nPrevLineState[nDevice] != DSL_LINESTATE_SHOWTIME_TC_SYNC) )
|
||||
{
|
||||
if (DSL_CPE_SetEnv("DSL_INTERFACE_STATUS", "UP") == DSL_SUCCESS)
|
||||
71
package/network/config/ltq-vdsl-app/Makefile
Normal file
71
package/network/config/ltq-vdsl-app/Makefile
Normal file
@@ -0,0 +1,71 @@
|
||||
# Copyright (C) 2010 OpenWrt.org
|
||||
# Copyright (C) 2015-2016 Lantiq Beteiligungs GmbH & Co KG.
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=ltq-vdsl-app
|
||||
PKG_VERSION:=4.17.18.6
|
||||
PKG_RELEASE:=2
|
||||
PKG_BASE_NAME:=dsl_cpe_control
|
||||
PKG_SOURCE:=$(PKG_BASE_NAME)_vrx-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
|
||||
PKG_HASH:=da8bb929526a61aea0e153ef524331fcd472a1ebbc6d88ca017735a4f82ece02
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_BASE_NAME)-$(PKG_VERSION)
|
||||
PKG_LICENSE:=BSD-2-Clause
|
||||
|
||||
PKG_BUILD_DEPENDS:=ltq-vdsl
|
||||
|
||||
PKG_ASLR_PIE:=0
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ltq-vdsl-app
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Lantiq VDSL userland tool
|
||||
URL:=http://www.lantiq.com/
|
||||
DEPENDS:=@TARGET_lantiq_xrx200 +libpthread +librt
|
||||
endef
|
||||
|
||||
define Package/ltq-vdsl-app/description
|
||||
Userland tool needed to control Lantiq VDSL CPE
|
||||
endef
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-vrx \
|
||||
--enable-vrx-device=vr9 \
|
||||
--enable-driver-include="-I$(STAGING_DIR)/usr/include/drv_vdsl_cpe_api" \
|
||||
--enable-device-driver-include="-I$(STAGING_DIR)/usr/include/vdsl/" \
|
||||
--enable-ifxos \
|
||||
--enable-ifxos-include="-I$(STAGING_DIR)/usr/include/ifxos" \
|
||||
--enable-ifxos-library="-I$(STAGING_DIR)/usr/lib" \
|
||||
--enable-add-appl-cflags="-DMAX_CLI_PIPES=1" \
|
||||
--enable-debug \
|
||||
--disable-dti \
|
||||
--with-channels-per-line="1" \
|
||||
|
||||
#CONFIGURE_ARGS += --enable-model=full
|
||||
#CONFIGURE_ARGS += --enable-model=lite
|
||||
#CONFIGURE_ARGS += --enable-model=footprint
|
||||
CONFIGURE_ARGS += \
|
||||
--enable-model=typical \
|
||||
--enable-dsl-pm-showtime \
|
||||
--disable-dsl-ceoc
|
||||
#CONFIGURE_ARGS += --enable-model=debug
|
||||
|
||||
define Package/ltq-vdsl-app/install
|
||||
$(INSTALL_DIR) $(1)/etc/init.d $(1)/sbin $(1)/etc/hotplug.d/dsl
|
||||
$(INSTALL_BIN) ./files/dsl_control $(1)/etc/init.d/
|
||||
$(INSTALL_BIN) ./files/10_atm.sh $(1)/etc/hotplug.d/dsl
|
||||
$(INSTALL_BIN) ./files/10_ptm.sh $(1)/etc/hotplug.d/dsl
|
||||
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/src/dsl_cpe_control $(1)/sbin/vdsl_cpe_control
|
||||
$(INSTALL_BIN) ./files/dsl_cpe_pipe.sh $(1)/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ltq-vdsl-app))
|
||||
14
package/network/config/ltq-vdsl-app/files/10_atm.sh
Executable file
14
package/network/config/ltq-vdsl-app/files/10_atm.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$DSL_NOTIFICATION_TYPE" = "DSL_STATUS" ] && \
|
||||
[ "$DSL_TC_LAYER_STATUS" = "ATM" ] && \
|
||||
! grep -q "ltq_atm_vr9" /proc/modules || exit 0
|
||||
|
||||
logger -p daemon.notice -t "dsl-notify" "Switching to TC-Layer ATM"
|
||||
|
||||
if grep -q "ltq_ptm_vr9" /proc/modules ; then
|
||||
logger -p daemon.notice -t "dsl-notify" "Loading ATM driver while EFM/PTM driver is loaded is not possible. Reboot is needed."
|
||||
exit
|
||||
fi
|
||||
|
||||
modprobe ltq_atm_vr9
|
||||
14
package/network/config/ltq-vdsl-app/files/10_ptm.sh
Executable file
14
package/network/config/ltq-vdsl-app/files/10_ptm.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ "$DSL_NOTIFICATION_TYPE" = "DSL_STATUS" ] && \
|
||||
[ "$DSL_TC_LAYER_STATUS" = "EFM" ] && \
|
||||
! grep -q "ltq_ptm_vr9" /proc/modules || exit 0
|
||||
|
||||
logger -p daemon.notice -t "dsl-notify" "Switching to TC-Layer EFM/PTM"
|
||||
|
||||
if grep -q "ltq_atm_vr9" /proc/modules ; then
|
||||
logger -p daemon.notice -t "dsl-notify" "Loading EFM/PTM driver while ATM driver is loaded is not possible. Reboot is needed."
|
||||
exit
|
||||
fi
|
||||
|
||||
modprobe ltq_ptm_vr9
|
||||
314
package/network/config/ltq-vdsl-app/files/dsl_control
Normal file
314
package/network/config/ltq-vdsl-app/files/dsl_control
Normal file
@@ -0,0 +1,314 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2012 OpenWrt.org
|
||||
|
||||
START=97
|
||||
USE_PROCD=1
|
||||
|
||||
EXTRA_COMMANDS="status lucistat"
|
||||
EXTRA_HELP=" status Get DSL status information
|
||||
lucistat Get status information if lua friendly format"
|
||||
|
||||
[ -f /lib/functions/lantiq_dsl.sh ] && . /lib/functions/lantiq_dsl.sh
|
||||
|
||||
#
|
||||
# ITU-T G.997.1 (06/2012) - Section 7.3.1.1.1 (xTU transmission system enabling (XTSE))
|
||||
# ITU-T G.997.1 Amendment 2 (04/2013) - Section 2.1 - (Vectoring mode enable (VECTORMODE_ENABLE))
|
||||
#
|
||||
# G.992.1 Annex A
|
||||
# G.992.2 Annex A
|
||||
# G.992.3 Annex A / L-US1 / L_US-2 / M
|
||||
# G.992.5 Annex A / M
|
||||
# G.993.2 Annex A/B/C
|
||||
# G.993.5 Annex A/B/C
|
||||
xtse_xdsl_a="05_01_04_00_4C_01_04_07"
|
||||
|
||||
# G.992.1 Annex B
|
||||
# G.992.3 Annex B
|
||||
# G.992.5 Annex B
|
||||
# G.993.2 Annex A/B/C
|
||||
# G.993.5 Annex A/B/C
|
||||
xtse_xdsl_b="10_00_10_00_00_04_00_07"
|
||||
|
||||
# G.992.1 Annex B
|
||||
# G.992.3 Annex B
|
||||
# G.992.3 Annex J
|
||||
# G.992.5 Annex B
|
||||
# G.992.5 Annex J
|
||||
# G.993.2 Annex A/B/C
|
||||
# G.993.5 Annex A/B/C
|
||||
xtse_xdsl_j="10_00_10_40_00_04_01_07"
|
||||
|
||||
# G.992.1 Annex B
|
||||
xtse_xdsl_bdmt="10_00_00_00_00_00_00_00"
|
||||
|
||||
# G.992.3 Annex B
|
||||
xtse_xdsl_b2="00_00_10_00_00_00_00_00"
|
||||
|
||||
# G.992.5 Annex B
|
||||
xtse_xdsl_b2p="00_00_00_00_00_04_00_00"
|
||||
|
||||
# ANSI T1.413
|
||||
xtse_xdsl_at1="01_00_00_00_00_00_00_00"
|
||||
|
||||
# G.992.2 Annex A
|
||||
xtse_xdsl_alite="00_01_00_00_00_00_00_00"
|
||||
|
||||
# G.992.1 Annex A
|
||||
xtse_xdsl_admt="04_00_00_00_00_00_00_00"
|
||||
|
||||
# G.992.3 Annex A
|
||||
xtse_xdsl_a2="00_00_04_00_00_00_00_00"
|
||||
|
||||
# G.992.5 Annex A
|
||||
xtse_xdsl_a2p="00_00_00_00_00_01_00_00"
|
||||
|
||||
# G.992.3 Annex L
|
||||
xtse_xdsl_l="00_00_00_00_0C_00_00_00"
|
||||
|
||||
# G.992.3 Annex M
|
||||
# G.992.5 Annex M
|
||||
xtse_xdsl_m="00_00_00_00_40_00_04_00"
|
||||
|
||||
# G.992.3 Annex M
|
||||
xtse_xdsl_m2="00_00_00_00_40_00_00_00"
|
||||
|
||||
# G.992.5 Annex M
|
||||
xtse_xdsl_m2p="00_00_00_00_00_00_04_00"
|
||||
|
||||
#
|
||||
# ITU-T G.994.1 (06/2012) - Table 2 (Mandatory carrier sets)
|
||||
#
|
||||
|
||||
# A43
|
||||
tone_adsl_a="0x142" # A43C + J43 + A43
|
||||
tone_vdsl_a="0x142" # A43C + J43 + A43
|
||||
|
||||
# A43 + V43
|
||||
tone_adsl_av="0x142" # A43C + J43 + A43
|
||||
tone_vdsl_av="0x146" # A43C + J43 + A43 + V43
|
||||
|
||||
# B43
|
||||
tone_adsl_b="0x81" # B43 + B43c
|
||||
tone_vdsl_b="0x1" # B43
|
||||
|
||||
# B43 + V43
|
||||
tone_adsl_bv="0x81" # B43 + B43c
|
||||
tone_vdsl_bv="0x5" # B43 + V43
|
||||
|
||||
# create ADSL autoboot script. Used for SNR margin tweak
|
||||
autoboot_script() {
|
||||
echo "[WaitForConfiguration]={
|
||||
locs 0 $1
|
||||
}
|
||||
|
||||
[WaitForLinkActivate]={
|
||||
}
|
||||
|
||||
[WaitForRestart]={
|
||||
}
|
||||
|
||||
[Common]={
|
||||
}" > /tmp/dsl.scr
|
||||
}
|
||||
|
||||
lowlevel_cfg() {
|
||||
echo "# VRX Low Level Configuration File
|
||||
#
|
||||
# Parameters must be separated by tabs or spaces.
|
||||
# Empty lines and comments will be ignored.
|
||||
#
|
||||
|
||||
# nFilter
|
||||
#
|
||||
# NA = -1
|
||||
# OFF = 0
|
||||
# ISDN = 1
|
||||
# POTS = 2
|
||||
# POTS_2 = 3
|
||||
# POTS_3 = 4
|
||||
#
|
||||
# (dec)
|
||||
-1
|
||||
|
||||
# nHsToneGroupMode nHsToneGroup_A nHsToneGroup_V nHsToneGroup_AV
|
||||
#
|
||||
# NA = -1 NA = -1 see see
|
||||
# AUTO = 0 VDSL2_B43 = 0x0001 nHsToneGroup_A nHsToneGroup_A
|
||||
# MANUAL = 1 VDSL2_A43 = 0x0002
|
||||
# VDSL2_V43 = 0x0004
|
||||
# VDSL1_V43P = 0x0008
|
||||
# VDSL1_V43I = 0x0010
|
||||
# ADSL1_C43 = 0x0020
|
||||
# ADSL2_J43 = 0x0040
|
||||
# ADSL2_B43C = 0x0080
|
||||
# ADSL2_A43C = 0x0100
|
||||
#
|
||||
# (dec) (hex) (hex) (hex)
|
||||
1 $1 $2 0x0
|
||||
|
||||
# nBaseAddr nIrqNum
|
||||
#
|
||||
# (hex) (dec)
|
||||
0x1e116000 63
|
||||
|
||||
# nUtopiaPhyAdr nUtopiaBusWidth nPosPhyParity
|
||||
# default(16b) = 0 NA = -1
|
||||
# 8-bit = 1 ODD = 0
|
||||
# 16-bit = 2
|
||||
#
|
||||
#
|
||||
# (hex) (dec) (dec)
|
||||
0xFF 0 0
|
||||
|
||||
# bNtrEnable
|
||||
#
|
||||
# (dec)
|
||||
0" > /tmp/lowlevel.cfg
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger network
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local annex
|
||||
local firmware
|
||||
local tone
|
||||
local tone_adsl
|
||||
local tone_vdsl
|
||||
local xtse
|
||||
local xfer_mode
|
||||
local line_mode
|
||||
local tc_layer
|
||||
local mode
|
||||
local lowlevel
|
||||
local snr
|
||||
|
||||
config_load network
|
||||
config_get tone dsl tone
|
||||
config_get annex dsl annex
|
||||
config_get firmware dsl firmware
|
||||
config_get xfer_mode dsl xfer_mode
|
||||
config_get line_mode dsl line_mode
|
||||
config_get snr dsl ds_snr_offset
|
||||
|
||||
eval "xtse=\"\${xtse_xdsl_$annex}\""
|
||||
|
||||
case "${xfer_mode}" in
|
||||
atm)
|
||||
tc_layer="-T1:0x1:0x1_1:0x1:0x1"
|
||||
;;
|
||||
ptm)
|
||||
tc_layer="-T2:0x1:0x1_2:0x1:0x1"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${line_mode}" in
|
||||
adsl)
|
||||
mode="-M1"
|
||||
|
||||
# mask out VDSL bits when ADSL is requested
|
||||
xtse="${xtse%_*}_00"
|
||||
;;
|
||||
vdsl)
|
||||
mode="-M2"
|
||||
|
||||
# mask out ADSL bits when VDSL is requested
|
||||
xtse="00_00_00_00_00_00_00_${xtse##*_}"
|
||||
;;
|
||||
esac
|
||||
|
||||
local annexgpio="/sys/class/gpio/annex"
|
||||
if [ -d "${annexgpio}a" ] && [ -d "${annexgpio}b" ]; then
|
||||
case "${annex}" in
|
||||
a*|l*|m*)
|
||||
echo 1 > "${annexgpio}a/value"
|
||||
echo 0 > "${annexgpio}b/value"
|
||||
;;
|
||||
b*|j*)
|
||||
echo 0 > "${annexgpio}a/value"
|
||||
echo 1 > "${annexgpio}b/value"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ -z "${firmware}" ]; then
|
||||
# search for the firmware provided by dsl-vrx200-firmware-xdsl-*
|
||||
if grep -qE "system type.*: (VR9|xRX200)" /proc/cpuinfo; then
|
||||
case "${annex}" in
|
||||
a*|l*|m*)
|
||||
if [ -f "/lib/firmware/lantiq-vrx200-a.bin" ]; then
|
||||
firmware="/lib/firmware/lantiq-vrx200-a.bin"
|
||||
elif [ -f "/tmp/lantiq-vrx200-a.bin" ]; then
|
||||
firmware="/tmp/lantiq-vrx200-a.bin"
|
||||
elif [ -f "/lib/firmware/lantiq-vrx200-b.bin" ] && [ -f "/lib/firmware/lantiq-vrx200-b-to-a.bspatch" ]; then
|
||||
bspatch /lib/firmware/lantiq-vrx200-b.bin \
|
||||
/tmp/lantiq-vrx200-a.bin \
|
||||
/lib/firmware/lantiq-vrx200-b-to-a.bspatch
|
||||
firmware="/tmp/lantiq-vrx200-a.bin"
|
||||
else
|
||||
echo "firmware for annex a not found"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
b*|j*)
|
||||
if [ -f "/lib/firmware/lantiq-vrx200-b.bin" ]; then
|
||||
firmware="/lib/firmware/lantiq-vrx200-b.bin"
|
||||
elif [ -f "/tmp/lantiq-vrx200-b.bin" ]; then
|
||||
firmware="/tmp/lantiq-vrx200-b.bin"
|
||||
elif [ -f "/lib/firmware/lantiq-vrx200-a.bin" ] && [ -f "/lib/firmware/lantiq-vrx200-a-to-b.bspatch" ]; then
|
||||
bspatch /lib/firmware/lantiq-vrx200-a.bin \
|
||||
/tmp/lantiq-vrx200-b.bin \
|
||||
/lib/firmware/lantiq-vrx200-a-to-b.bspatch
|
||||
firmware="/tmp/lantiq-vrx200-b.bin"
|
||||
else
|
||||
echo "firmware for annex b not found"
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "annex type not supported use a or b"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -z "${firmware}" ] && firmware=/lib/firmware/vdsl.bin
|
||||
[ -f "${firmware}" ] || {
|
||||
echo failed to find $firmware
|
||||
return 1
|
||||
}
|
||||
|
||||
eval "tone_adsl=\"\${tone_adsl_$tone}\""
|
||||
eval "tone_vdsl=\"\${tone_vdsl_$tone}\""
|
||||
[ -n "${tone_adsl}" ] && [ -n "${tone_vdsl}" ] && {
|
||||
lowlevel_cfg "${tone_adsl}" "${tone_vdsl}"
|
||||
lowlevel="-l /tmp/lowlevel.cfg"
|
||||
}
|
||||
|
||||
[ -z "${snr}" ] || {
|
||||
# for SNR offset setting
|
||||
autoboot_script "$snr"
|
||||
autoboot="-a /tmp/dsl.scr -A /tmp/dsl.scr"
|
||||
}
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /sbin/vdsl_cpe_control \
|
||||
-i$xtse \
|
||||
-n /sbin/dsl_notify.sh \
|
||||
-f ${firmware} \
|
||||
$lowlevel \
|
||||
${mode} \
|
||||
${tc_layer} \
|
||||
$autoboot
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
# do not use dsl_cmd to not block when this is locked up by some other proess
|
||||
echo quit > /tmp/pipe/dsl_cpe0_cmd
|
||||
DSL_NOTIFICATION_TYPE="DSL_INTERFACE_STATUS" \
|
||||
DSL_INTERFACE_STATUS="DOWN" \
|
||||
/sbin/dsl_notify.sh
|
||||
}
|
||||
18
package/network/config/ltq-vdsl-app/files/dsl_cpe_pipe.sh
Executable file
18
package/network/config/ltq-vdsl-app/files/dsl_cpe_pipe.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
pipe_no=0
|
||||
|
||||
# use specified pipe no
|
||||
case "$1" in
|
||||
0|1|2)
|
||||
pipe_no=$1; shift; ;;
|
||||
esac
|
||||
|
||||
|
||||
#echo "Call dsl_pipe with $*"
|
||||
lock /var/lock/dsl_pipe
|
||||
echo $* > /tmp/pipe/dsl_cpe${pipe_no}_cmd
|
||||
result=`cat /tmp/pipe/dsl_cpe${pipe_no}_ack`
|
||||
lock -u /var/lock/dsl_pipe
|
||||
|
||||
echo "$result"
|
||||
22
package/network/config/ltq-vdsl-app/patches/100-compat.patch
Normal file
22
package/network/config/ltq-vdsl-app/patches/100-compat.patch
Normal file
@@ -0,0 +1,22 @@
|
||||
--- a/src/dsl_cpe_init_cfg.c
|
||||
+++ b/src/dsl_cpe_init_cfg.c
|
||||
@@ -38,7 +38,7 @@ DSL_InitData_t gInitCfgData =
|
||||
DSL_DEV_HS_TONE_GROUP_CLEANED, \
|
||||
DSL_DEV_HS_TONE_GROUP_CLEANED, \
|
||||
DSL_DEV_HS_TONE_GROUP_CLEANED, \
|
||||
- 0x1E116000, 0x37, -1),
|
||||
+ 0x1E116000, 0x3f, -1),
|
||||
DSL_CPE_SIC_SET(DSL_TC_ATM, DSL_EMF_TC_CLEANED, DSL_EMF_TC_CLEANED, DSL_SYSTEMIF_MII, \
|
||||
DSL_TC_EFM, DSL_EMF_TC_CLEANED, DSL_EMF_TC_CLEANED, DSL_SYSTEMIF_MII),
|
||||
DSL_CPE_MAC_CFG_SET(DSL_EFM_SPEED_100, DSL_EFM_DUPLEX_FULL, DSL_EFM_FLOWCTRL_ON, DSL_EFM_AUTONEG_OFF, \
|
||||
--- a/src/dsl_cpe_control.c
|
||||
+++ b/src/dsl_cpe_control.c
|
||||
@@ -6761,7 +6761,7 @@ DSL_int_t dsl_cpe_daemon (
|
||||
for (nDevice = 0; nDevice < DSL_CPE_MAX_DSL_ENTITIES; nDevice++)
|
||||
{
|
||||
#if defined(INCLUDE_DSL_CPE_API_VRX)
|
||||
- sprintf (device, "%s/%d", DSL_CPE_DEVICE_NAME, nDevice);
|
||||
+ sprintf (device, "%s%d", DSL_CPE_DEVICE_NAME, nDevice);
|
||||
#else
|
||||
sprintf (device, "%s", DSL_CPE_DEVICE_NAME);
|
||||
#endif /* defined(INCLUDE_DSL_CPE_API_VRX)*/
|
||||
10
package/network/config/ltq-vdsl-app/patches/101-musl.patch
Normal file
10
package/network/config/ltq-vdsl-app/patches/101-musl.patch
Normal file
@@ -0,0 +1,10 @@
|
||||
--- a/src/dsl_cpe_control.c
|
||||
+++ b/src/dsl_cpe_control.c
|
||||
@@ -11,6 +11,7 @@
|
||||
/*
|
||||
Includes
|
||||
*/
|
||||
+#include <limits.h>
|
||||
#include "dsl_cpe_control.h"
|
||||
#include "dsl_cpe_cli.h"
|
||||
#include "dsl_cpe_cli_console.h"
|
||||
@@ -0,0 +1,11 @@
|
||||
--- a/src/dsl_cpe_init_cfg.c
|
||||
+++ b/src/dsl_cpe_init_cfg.c
|
||||
@@ -27,7 +27,7 @@ DSL_InitData_t gInitCfgData =
|
||||
DSL_CPE_FW2_SET(DSL_NULL, 0x0),
|
||||
DSL_CPE_XTU_SET(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7),
|
||||
DSL_CPE_LINE_INV_NE_SET(DSL_NULL),
|
||||
- DSL_CPE_AUTOBOOT_CTRL_SET(DSL_AUTOBOOT_CTRL_STOP),
|
||||
+ DSL_CPE_AUTOBOOT_CTRL_SET(DSL_AUTOBOOT_CTRL_START),
|
||||
DSL_CPE_AUTOBOOT_CFG_SET(DSL_FALSE, DSL_FALSE, DSL_FALSE),
|
||||
DSL_CPE_TEST_MODE_CTRL_SET(DSL_TESTMODE_DISABLE),
|
||||
DSL_CPE_LINE_ACTIVATE_CTRL_SET(DSL_G997_INHIBIT_LDSF, DSL_G997_INHIBIT_ACSF, DSL_G997_NORMAL_STARTUP),
|
||||
43
package/network/config/netifd/Makefile
Normal file
43
package/network/config/netifd/Makefile
Normal file
@@ -0,0 +1,43 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=netifd
|
||||
PKG_RELEASE:=2.1
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git
|
||||
PKG_SOURCE_DATE:=2019-01-31
|
||||
PKG_SOURCE_VERSION:=a2aba5c7ae574452a9f81e9d788afecdd8ec07b2
|
||||
PKG_MIRROR_HASH:=c5ff34aa401549e377c9e4ee5ce7443796a02bea743ecdc73f439cd942914c8d
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/netifd
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libuci +libnl-tiny +libubus +ubus +ubusd +jshn +libubox
|
||||
TITLE:=OpenWrt Network Interface Configuration Daemon
|
||||
endef
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(STAGING_DIR)/usr/include/libnl-tiny \
|
||||
-I$(STAGING_DIR)/usr/include
|
||||
|
||||
CMAKE_OPTIONS += \
|
||||
-DLIBNL_LIBS=-lnl-tiny \
|
||||
-DDEBUG=1
|
||||
|
||||
define Package/netifd/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/netifd $(1)/sbin/
|
||||
$(CP) ./files/* $(1)/
|
||||
$(CP) $(PKG_BUILD_DIR)/scripts/* $(1)/lib/netifd/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,netifd))
|
||||
@@ -0,0 +1,6 @@
|
||||
[ ifup = "$ACTION" ] && {
|
||||
uci_toggle_state network "$INTERFACE" up 1
|
||||
[ -n "$DEVICE" ] && {
|
||||
uci_toggle_state network "$INTERFACE" ifname "$DEVICE"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/bin/sh
|
||||
[ "$ACTION" = add ] || exit
|
||||
|
||||
NPROCS="$(grep -c "^processor.*:" /proc/cpuinfo)"
|
||||
[ "$NPROCS" -gt 1 ] || exit
|
||||
|
||||
PROC_MASK="$(( (1 << $NPROCS) - 1 ))"
|
||||
|
||||
find_irq_cpu() {
|
||||
local dev="$1"
|
||||
local match="$(grep -m 1 "$dev\$" /proc/interrupts)"
|
||||
local cpu=0
|
||||
|
||||
[ -n "$match" ] && {
|
||||
set -- $match
|
||||
shift
|
||||
for cur in `seq 1 $NPROCS`; do
|
||||
[ "$1" -gt 0 ] && {
|
||||
cpu=$(($cur - 1))
|
||||
break
|
||||
}
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
echo "$cpu"
|
||||
}
|
||||
|
||||
set_hex_val() {
|
||||
local file="$1"
|
||||
local val="$2"
|
||||
val="$(printf %x "$val")"
|
||||
[ -n "$DEBUG" ] && echo "$file = $val"
|
||||
echo "$val" > "$file"
|
||||
}
|
||||
|
||||
default_ps="$(uci get "network.@globals[0].default_ps")"
|
||||
[ -n "$default_ps" -a "$default_ps" != 1 ] && exit 0
|
||||
|
||||
exec 512>/var/lock/smp_tune.lock
|
||||
flock 512 || exit 1
|
||||
|
||||
for dev in /sys/class/net/*; do
|
||||
[ -d "$dev" ] || continue
|
||||
|
||||
# ignore virtual interfaces
|
||||
[ -n "$(ls "${dev}/" | grep '^lower_')" ] && continue
|
||||
[ -d "${dev}/device" ] || continue
|
||||
|
||||
device="$(readlink "${dev}/device")"
|
||||
device="$(basename "$device")"
|
||||
irq_cpu="$(find_irq_cpu "$device")"
|
||||
irq_cpu_mask="$((1 << $irq_cpu))"
|
||||
|
||||
for q in ${dev}/queues/rx-*; do
|
||||
set_hex_val "$q/rps_cpus" "$(($PROC_MASK & ~$irq_cpu_mask))"
|
||||
done
|
||||
|
||||
ntxq="$(ls -d ${dev}/queues/tx-* | wc -l)"
|
||||
|
||||
idx=$(($irq_cpu + 1))
|
||||
for q in ${dev}/queues/tx-*; do
|
||||
set_hex_val "$q/xps_cpus" "$((1 << $idx))"
|
||||
let "idx = idx + 1"
|
||||
[ "$idx" -ge "$NPROCS" ] && idx=0
|
||||
done
|
||||
done
|
||||
147
package/network/config/netifd/files/etc/init.d/network
Executable file
147
package/network/config/netifd/files/etc/init.d/network
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
START=20
|
||||
STOP=90
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
init_switch() {
|
||||
setup_switch() { return 0; }
|
||||
|
||||
include /lib/network
|
||||
setup_switch
|
||||
}
|
||||
|
||||
start_service() {
|
||||
init_switch
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /sbin/netifd
|
||||
procd_set_param respawn
|
||||
procd_set_param watch network.interface
|
||||
[ -e /proc/sys/kernel/core_pattern ] && {
|
||||
procd_set_param limits core="unlimited"
|
||||
}
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
local rv=0
|
||||
|
||||
init_switch
|
||||
ubus call network reload || rv=1
|
||||
/sbin/wifi reload_legacy
|
||||
return $rv
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
/sbin/wifi down
|
||||
ifdown -a
|
||||
sleep 1
|
||||
}
|
||||
|
||||
service_running() {
|
||||
ubus -t 30 wait_for network.interface
|
||||
/sbin/wifi reload_legacy
|
||||
}
|
||||
|
||||
validate_atm_bridge_section()
|
||||
{
|
||||
uci_validate_section network "atm-bridge" "${1}" \
|
||||
'unit:uinteger:0' \
|
||||
'vci:range(32, 65535):35' \
|
||||
'vpi:range(0, 255):8' \
|
||||
'atmdev:uinteger:0' \
|
||||
'encaps:or("llc", "vc"):llc' \
|
||||
'payload:or("bridged", "routed"):bridged'
|
||||
}
|
||||
|
||||
validate_route_section()
|
||||
{
|
||||
uci_validate_section network route "${1}" \
|
||||
'interface:string' \
|
||||
'target:cidr4' \
|
||||
'netmask:netmask4' \
|
||||
'gateway:ip4addr' \
|
||||
'metric:uinteger' \
|
||||
'mtu:uinteger' \
|
||||
'table:or(range(0,65535),string)'
|
||||
}
|
||||
|
||||
validate_route6_section()
|
||||
{
|
||||
uci_validate_section network route6 "${1}" \
|
||||
'interface:string' \
|
||||
'target:cidr6' \
|
||||
'gateway:ip6addr' \
|
||||
'metric:uinteger' \
|
||||
'mtu:uinteger' \
|
||||
'table:or(range(0,65535),string)'
|
||||
}
|
||||
|
||||
validate_rule_section()
|
||||
{
|
||||
uci_validate_section network rule "${1}" \
|
||||
'in:string' \
|
||||
'out:string' \
|
||||
'src:cidr4' \
|
||||
'dest:cidr4' \
|
||||
'tos:range(0,31)' \
|
||||
'mark:string' \
|
||||
'invert:bool' \
|
||||
'lookup:or(range(0,65535),string)' \
|
||||
'goto:range(0,65535)' \
|
||||
'action:or("prohibit", "unreachable", "blackhole", "throw")'
|
||||
}
|
||||
|
||||
validate_rule6_section()
|
||||
{
|
||||
uci_validate_section network rule6 "${1}" \
|
||||
'in:string' \
|
||||
'out:string' \
|
||||
'src:cidr6' \
|
||||
'dest:cidr6' \
|
||||
'tos:range(0,31)' \
|
||||
'mark:string' \
|
||||
'invert:bool' \
|
||||
'lookup:or(range(0,65535),string)' \
|
||||
'goto:range(0,65535)' \
|
||||
'action:or("prohibit", "unreachable", "blackhole", "throw")'
|
||||
}
|
||||
|
||||
validate_switch_section()
|
||||
{
|
||||
uci_validate_section network switch "${1}" \
|
||||
'name:string' \
|
||||
'enable:bool' \
|
||||
'enable_vlan:bool' \
|
||||
'reset:bool'
|
||||
}
|
||||
|
||||
validate_switch_vlan()
|
||||
{
|
||||
uci_validate_section network switch_vlan "${1}" \
|
||||
'device:string' \
|
||||
'vlan:uinteger' \
|
||||
'ports:list(ports)'
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger network wireless
|
||||
|
||||
procd_open_validate
|
||||
validate_atm_bridge_section
|
||||
validate_route_section
|
||||
[ -e /proc/sys/net/ipv6 ] && validate_route6_section
|
||||
validate_rule_section
|
||||
[ -e /proc/sys/net/ipv6 ] && validate_rule6_section
|
||||
validate_switch_section
|
||||
validate_switch_vlan
|
||||
procd_close_validate
|
||||
}
|
||||
|
||||
shutdown() {
|
||||
ifdown -a
|
||||
sleep 1
|
||||
}
|
||||
110
package/network/config/netifd/files/lib/netifd/dhcp.script
Executable file
110
package/network/config/netifd/files/lib/netifd/dhcp.script
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/bin/sh
|
||||
[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/netifd/netifd-proto.sh
|
||||
|
||||
set_classless_routes() {
|
||||
local max=128
|
||||
while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do
|
||||
proto_add_ipv4_route "${1%%/*}" "${1##*/}" "$2" "$ip"
|
||||
max=$(($max-1))
|
||||
shift 2
|
||||
done
|
||||
}
|
||||
|
||||
setup_interface () {
|
||||
proto_init_update "*" 1
|
||||
proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}"
|
||||
# TODO: apply $broadcast
|
||||
|
||||
local ip_net
|
||||
eval "$(ipcalc.sh "$ip/$mask")";ip_net="$NETWORK"
|
||||
|
||||
local i
|
||||
for i in $router; do
|
||||
local gw_net
|
||||
eval "$(ipcalc.sh "$i/$mask")";gw_net="$NETWORK"
|
||||
|
||||
[ "$ip_net" != "$gw_net" ] && proto_add_ipv4_route "$i" 32 "" "$ip"
|
||||
proto_add_ipv4_route 0.0.0.0 0 "$i" "$ip"
|
||||
|
||||
local r
|
||||
for r in $CUSTOMROUTES; do
|
||||
proto_add_ipv4_route "${r%%/*}" "${r##*/}" "$i" "$ip"
|
||||
done
|
||||
done
|
||||
|
||||
# CIDR STATIC ROUTES (rfc3442)
|
||||
[ -n "$staticroutes" ] && set_classless_routes $staticroutes
|
||||
[ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes
|
||||
|
||||
for i in $dns; do
|
||||
proto_add_dns_server "$i"
|
||||
done
|
||||
for i in $domain; do
|
||||
proto_add_dns_search "$i"
|
||||
done
|
||||
|
||||
proto_add_data
|
||||
[ -n "$ZONE" ] && json_add_string zone "$ZONE"
|
||||
[ -n "$ntpsrv" ] && json_add_string ntpserver "$ntpsrv"
|
||||
[ -n "$timesvr" ] && json_add_string timeserver "$timesvr"
|
||||
[ -n "$hostname" ] && json_add_string hostname "$hostname"
|
||||
[ -n "$message" ] && json_add_string message "$message"
|
||||
[ -n "$timezone" ] && json_add_int timezone "$timezone"
|
||||
[ -n "$lease" ] && json_add_int leasetime "$lease"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$INTERFACE"
|
||||
|
||||
|
||||
if [ "$IFACE6RD" != 0 -a -n "$ip6rd" ]; then
|
||||
local v4mask="${ip6rd%% *}"
|
||||
ip6rd="${ip6rd#* }"
|
||||
local ip6rdprefixlen="${ip6rd%% *}"
|
||||
ip6rd="${ip6rd#* }"
|
||||
local ip6rdprefix="${ip6rd%% *}"
|
||||
ip6rd="${ip6rd#* }"
|
||||
local ip6rdbr="${ip6rd%% *}"
|
||||
|
||||
[ -n "$ZONE" ] || ZONE=$(fw3 -q network $INTERFACE 2>/dev/null)
|
||||
[ -z "$IFACE6RD" -o "$IFACE6RD" = 1 ] && IFACE6RD=${INTERFACE}_6
|
||||
|
||||
json_init
|
||||
json_add_string name "$IFACE6RD"
|
||||
json_add_string ifname "@$INTERFACE"
|
||||
json_add_string proto "6rd"
|
||||
json_add_string peeraddr "$ip6rdbr"
|
||||
json_add_int ip4prefixlen "$v4mask"
|
||||
json_add_string ip6prefix "$ip6rdprefix"
|
||||
json_add_int ip6prefixlen "$ip6rdprefixlen"
|
||||
json_add_string tunlink "$INTERFACE"
|
||||
[ -n "$IFACE6RD_DELEGATE" ] && json_add_boolean delegate "$IFACE6RD_DELEGATE"
|
||||
[ -n "$ZONE6RD" ] || ZONE6RD=$ZONE
|
||||
[ -n "$ZONE6RD" ] && json_add_string zone "$ZONE6RD"
|
||||
[ -n "$MTU6RD" ] && json_add_string mtu "$MTU6RD"
|
||||
json_close_object
|
||||
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
fi
|
||||
}
|
||||
|
||||
deconfig_interface() {
|
||||
proto_init_update "*" 0
|
||||
proto_send_update "$INTERFACE"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
deconfig)
|
||||
deconfig_interface
|
||||
;;
|
||||
renew|bound)
|
||||
setup_interface
|
||||
;;
|
||||
esac
|
||||
|
||||
# user rules
|
||||
[ -f /etc/udhcpc.user ] && . /etc/udhcpc.user "$@"
|
||||
|
||||
exit 0
|
||||
88
package/network/config/netifd/files/lib/netifd/proto/dhcp.sh
Executable file
88
package/network/config/netifd/files/lib/netifd/proto/dhcp.sh
Executable file
@@ -0,0 +1,88 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -L /sbin/udhcpc ] || exit 0
|
||||
|
||||
. /lib/functions.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
|
||||
proto_dhcp_init_config() {
|
||||
renew_handler=1
|
||||
|
||||
proto_config_add_string 'ipaddr:ipaddr'
|
||||
proto_config_add_string 'hostname:hostname'
|
||||
proto_config_add_string clientid
|
||||
proto_config_add_string vendorid
|
||||
proto_config_add_boolean 'broadcast:bool'
|
||||
proto_config_add_boolean 'release:bool'
|
||||
proto_config_add_string 'reqopts:list(string)'
|
||||
proto_config_add_boolean 'defaultreqopts:bool'
|
||||
proto_config_add_string iface6rd
|
||||
proto_config_add_array 'sendopts:list(string)'
|
||||
proto_config_add_boolean delegate
|
||||
proto_config_add_string zone6rd
|
||||
proto_config_add_string zone
|
||||
proto_config_add_string mtu6rd
|
||||
proto_config_add_string customroutes
|
||||
proto_config_add_boolean classlessroute
|
||||
}
|
||||
|
||||
proto_dhcp_add_sendopts() {
|
||||
[ -n "$1" ] && append "$3" "-x $1"
|
||||
}
|
||||
|
||||
proto_dhcp_setup() {
|
||||
local config="$1"
|
||||
local iface="$2"
|
||||
|
||||
local ipaddr hostname clientid vendorid broadcast release reqopts defaultreqopts iface6rd sendopts delegate zone6rd zone mtu6rd customroutes classlessroute
|
||||
json_get_vars ipaddr hostname clientid vendorid broadcast release reqopts defaultreqopts iface6rd delegate zone6rd zone mtu6rd customroutes classlessroute
|
||||
|
||||
local opt dhcpopts
|
||||
for opt in $reqopts; do
|
||||
append dhcpopts "-O $opt"
|
||||
done
|
||||
|
||||
json_for_each_item proto_dhcp_add_sendopts sendopts dhcpopts
|
||||
|
||||
[ -z "$hostname" ] && hostname="$(cat /proc/sys/kernel/hostname)"
|
||||
[ "$hostname" = "*" ] && hostname=
|
||||
|
||||
[ "$defaultreqopts" = 0 ] && defaultreqopts="-o" || defaultreqopts=
|
||||
[ "$broadcast" = 1 ] && broadcast="-B" || broadcast=
|
||||
[ "$release" = 1 ] && release="-R" || release=
|
||||
[ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" || clientid="-C"
|
||||
[ -n "$iface6rd" ] && proto_export "IFACE6RD=$iface6rd"
|
||||
[ "$iface6rd" != 0 -a -f /lib/netifd/proto/6rd.sh ] && append dhcpopts "-O 212"
|
||||
[ -n "$zone6rd" ] && proto_export "ZONE6RD=$zone6rd"
|
||||
[ -n "$zone" ] && proto_export "ZONE=$zone"
|
||||
[ -n "$mtu6rd" ] && proto_export "MTU6RD=$mtu6rd"
|
||||
[ -n "$customroutes" ] && proto_export "CUSTOMROUTES=$customroutes"
|
||||
[ "$delegate" = "0" ] && proto_export "IFACE6RD_DELEGATE=0"
|
||||
# Request classless route option (see RFC 3442) by default
|
||||
[ "$classlessroute" = "0" ] || append dhcpopts "-O 121"
|
||||
|
||||
proto_export "INTERFACE=$config"
|
||||
proto_run_command "$config" udhcpc \
|
||||
-p /var/run/udhcpc-$iface.pid \
|
||||
-s /lib/netifd/dhcp.script \
|
||||
-f -t 0 -i "$iface" \
|
||||
${ipaddr:+-r $ipaddr} \
|
||||
${hostname:+-x "hostname:$hostname"} \
|
||||
${vendorid:+-V "$vendorid"} \
|
||||
$clientid $defaultreqopts $broadcast $release $dhcpopts
|
||||
}
|
||||
|
||||
proto_dhcp_renew() {
|
||||
local interface="$1"
|
||||
# SIGUSR1 forces udhcpc to renew its lease
|
||||
local sigusr1="$(kill -l SIGUSR1)"
|
||||
[ -n "$sigusr1" ] && proto_kill_command "$interface" $sigusr1
|
||||
}
|
||||
|
||||
proto_dhcp_teardown() {
|
||||
local interface="$1"
|
||||
proto_kill_command "$interface"
|
||||
}
|
||||
|
||||
add_protocol dhcp
|
||||
76
package/network/config/netifd/files/lib/network/config.sh
Executable file
76
package/network/config/netifd/files/lib/network/config.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2011 OpenWrt.org
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
find_config() {
|
||||
local device="$1"
|
||||
local ifdev ifl3dev ifobj
|
||||
for ifobj in `ubus list network.interface.\*`; do
|
||||
interface="${ifobj##network.interface.}"
|
||||
(
|
||||
json_load "$(ifstatus $interface)"
|
||||
json_get_var ifdev device
|
||||
json_get_var ifl3dev l3_device
|
||||
if [[ "$device" = "$ifdev" ]] || [[ "$device" = "$ifl3dev" ]]; then
|
||||
echo "$interface"
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
) && return
|
||||
done
|
||||
}
|
||||
|
||||
unbridge() {
|
||||
return
|
||||
}
|
||||
|
||||
ubus_call() {
|
||||
json_init
|
||||
local _data="$(ubus -S call "$1" "$2")"
|
||||
[ -z "$_data" ] && return 1
|
||||
json_load "$_data"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
fixup_interface() {
|
||||
local config="$1"
|
||||
local ifname type device l3dev
|
||||
|
||||
config_get type "$config" type
|
||||
config_get ifname "$config" ifname
|
||||
[ "bridge" = "$type" ] && ifname="br-$config"
|
||||
ubus_call "network.interface.$config" status || return 0
|
||||
json_get_var l3dev l3_device
|
||||
[ -n "$l3dev" ] && ifname="$l3dev"
|
||||
json_init
|
||||
config_set "$config" ifname "$ifname"
|
||||
}
|
||||
|
||||
scan_interfaces() {
|
||||
config_load network
|
||||
config_foreach fixup_interface interface
|
||||
}
|
||||
|
||||
prepare_interface_bridge() {
|
||||
local config="$1"
|
||||
|
||||
[ -n "$config" ] || return 0
|
||||
ubus call network.interface."$config" prepare
|
||||
}
|
||||
|
||||
setup_interface() {
|
||||
local iface="$1"
|
||||
local config="$2"
|
||||
|
||||
[ -n "$config" ] || return 0
|
||||
ubus call network.interface."$config" add_device "{ \"name\": \"$iface\" }"
|
||||
}
|
||||
|
||||
do_sysctl() {
|
||||
[ -n "$2" ] && \
|
||||
sysctl -n -e -w "$1=$2" >/dev/null || \
|
||||
sysctl -n -e "$1"
|
||||
}
|
||||
12
package/network/config/netifd/files/sbin/devstatus
Executable file
12
package/network/config/netifd/files/sbin/devstatus
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
DEVICE="$1"
|
||||
|
||||
[ -n "$DEVICE" ] || {
|
||||
echo "Usage: $0 <device>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
json_init
|
||||
json_add_string name "$DEVICE"
|
||||
ubus call network.device status "$(json_dump)"
|
||||
1
package/network/config/netifd/files/sbin/ifdown
Symbolic link
1
package/network/config/netifd/files/sbin/ifdown
Symbolic link
@@ -0,0 +1 @@
|
||||
ifup
|
||||
13
package/network/config/netifd/files/sbin/ifstatus
Executable file
13
package/network/config/netifd/files/sbin/ifstatus
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
INTERFACE="$1"
|
||||
|
||||
[ -n "$INTERFACE" ] || {
|
||||
echo "Usage: $0 <interface>"
|
||||
exit 1
|
||||
}
|
||||
|
||||
ubus -S list "network.interface.$INTERFACE" >/dev/null || {
|
||||
echo "Interface $INTERFACE not found"
|
||||
exit 1
|
||||
}
|
||||
ubus call network.interface status "{ \"interface\" : \"$INTERFACE\" }"
|
||||
77
package/network/config/netifd/files/sbin/ifup
Executable file
77
package/network/config/netifd/files/sbin/ifup
Executable file
@@ -0,0 +1,77 @@
|
||||
#!/bin/sh
|
||||
|
||||
ifup_all=
|
||||
setup_wifi=
|
||||
|
||||
if_call() {
|
||||
local interface="$1"
|
||||
for mode in $modes; do
|
||||
ubus call network.interface $mode "{ \"interface\" : \"$interface\" }"
|
||||
done
|
||||
}
|
||||
|
||||
case "$0" in
|
||||
*ifdown) modes=down;;
|
||||
*ifup)
|
||||
modes="down up"
|
||||
setup_wifi=1
|
||||
;;
|
||||
*) echo "Invalid command: $0";;
|
||||
esac
|
||||
|
||||
while :; do
|
||||
case "$1" in
|
||||
-a)
|
||||
ifup_all=1
|
||||
shift
|
||||
;;
|
||||
-w)
|
||||
setup_wifi=
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$modes" = "down up" ] && ubus call network reload
|
||||
if [ -n "$ifup_all" ]; then
|
||||
for interface in `ubus -S list 'network.interface.*'`; do
|
||||
if_call "${interface##network.interface.}"
|
||||
done
|
||||
[ -n "$setup_wifi" ] && /sbin/wifi up
|
||||
exit
|
||||
else
|
||||
ubus -S list "network.interface.$1" > /dev/null || {
|
||||
echo "Interface $1 not found"
|
||||
exit
|
||||
}
|
||||
if_call "$1"
|
||||
fi
|
||||
|
||||
if [ -n "$setup_wifi" ] && grep -sq config /etc/config/wireless; then
|
||||
. /lib/functions.sh
|
||||
|
||||
find_related_radios() {
|
||||
local wdev wnet
|
||||
config_get wdev "$1" device
|
||||
config_get wnet "$1" network
|
||||
|
||||
if [ -n "$wdev" ]; then
|
||||
for wnet in $wnet; do
|
||||
if [ "$wnet" = "$network" ]; then
|
||||
append radio_devs "$wdev" "$N"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
network="$1"
|
||||
config_load wireless
|
||||
config_foreach find_related_radios wifi-iface
|
||||
|
||||
for dev in $(echo "$radio_devs" | sort -u); do
|
||||
/sbin/wifi up "$dev"
|
||||
done
|
||||
fi
|
||||
57
package/network/config/netifd/files/usr/share/udhcpc/default.script
Executable file
57
package/network/config/netifd/files/usr/share/udhcpc/default.script
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1
|
||||
|
||||
set_classless_routes() {
|
||||
local max=128
|
||||
local type
|
||||
while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do
|
||||
[ ${1##*/} -eq 32 ] && type=host || type=net
|
||||
echo "udhcpc: adding route for $type $1 via $2"
|
||||
route add -$type "$1" gw "$2" dev "$interface"
|
||||
max=$(($max-1))
|
||||
shift 2
|
||||
done
|
||||
}
|
||||
|
||||
setup_interface() {
|
||||
echo "udhcpc: ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}"
|
||||
ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}
|
||||
|
||||
[ -n "$router" ] && [ "$router" != "0.0.0.0" ] && [ "$router" != "255.255.255.255" ] && {
|
||||
echo "udhcpc: setting default routers: $router"
|
||||
|
||||
local valid_gw=""
|
||||
for i in $router ; do
|
||||
route add default gw $i dev $interface
|
||||
valid_gw="${valid_gw:+$valid_gw|}$i"
|
||||
done
|
||||
|
||||
eval $(route -n | awk '
|
||||
/^0.0.0.0\W{9}('$valid_gw')\W/ {next}
|
||||
/^0.0.0.0/ {print "route del -net "$1" gw "$2";"}
|
||||
')
|
||||
}
|
||||
|
||||
# CIDR STATIC ROUTES (rfc3442)
|
||||
[ -n "$staticroutes" ] && set_classless_routes $staticroutes
|
||||
[ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes
|
||||
}
|
||||
|
||||
|
||||
applied=
|
||||
case "$1" in
|
||||
deconfig)
|
||||
ifconfig "$interface" 0.0.0.0
|
||||
;;
|
||||
renew)
|
||||
setup_interface update
|
||||
;;
|
||||
bound)
|
||||
setup_interface ifup
|
||||
;;
|
||||
esac
|
||||
|
||||
# user rules
|
||||
[ -f /etc/udhcpc.user ] && . /etc/udhcpc.user
|
||||
|
||||
exit 0
|
||||
53
package/network/config/qos-scripts/Makefile
Normal file
53
package/network/config/qos-scripts/Makefile
Normal file
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Copyright (C) 2006-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=qos-scripts
|
||||
PKG_VERSION:=1.3.1
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/qos-scripts
|
||||
SECTION:=utils
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+tc +kmod-sched-core +kmod-sched-connmark +kmod-ifb +iptables +iptables-mod-ipopt +iptables-mod-conntrack-extra
|
||||
TITLE:=QoS scripts
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/qos-scripts/description
|
||||
A set of scripts that abstract QoS configuration into a simple
|
||||
configuration file supporting stanzas that specify any number of QoS
|
||||
entries.
|
||||
endef
|
||||
|
||||
define Package/qos-scripts/conffiles
|
||||
/etc/config/qos
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/qos-scripts/install
|
||||
$(INSTALL_DIR) $(1)
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,qos-scripts))
|
||||
68
package/network/config/qos-scripts/files/etc/config/qos
Normal file
68
package/network/config/qos-scripts/files/etc/config/qos
Normal file
@@ -0,0 +1,68 @@
|
||||
# QoS configuration for OpenWrt
|
||||
|
||||
# INTERFACES:
|
||||
config interface wan
|
||||
option classgroup "Default"
|
||||
option enabled 0
|
||||
option upload 128
|
||||
option download 1024
|
||||
|
||||
# RULES:
|
||||
config classify
|
||||
option target "Priority"
|
||||
option ports "22,53"
|
||||
option comment "ssh, dns"
|
||||
config classify
|
||||
option target "Normal"
|
||||
option proto "tcp"
|
||||
option ports "20,21,25,80,110,443,993,995"
|
||||
option comment "ftp, smtp, http(s), imap"
|
||||
config classify
|
||||
option target "Express"
|
||||
option ports "5190"
|
||||
option comment "AOL, iChat, ICQ"
|
||||
config default
|
||||
option target "Express"
|
||||
option proto "udp"
|
||||
option pktsize "-500"
|
||||
config reclassify
|
||||
option target "Priority"
|
||||
option proto "icmp"
|
||||
config default
|
||||
option target "Bulk"
|
||||
option portrange "1024-65535"
|
||||
|
||||
|
||||
# Don't change the stuff below unless you
|
||||
# really know what it means :)
|
||||
|
||||
config classgroup "Default"
|
||||
option classes "Priority Express Normal Bulk"
|
||||
option default "Normal"
|
||||
|
||||
|
||||
config class "Priority"
|
||||
option packetsize 400
|
||||
option avgrate 10
|
||||
option priority 20
|
||||
config class "Priority_down"
|
||||
option packetsize 1000
|
||||
option avgrate 10
|
||||
|
||||
|
||||
config class "Express"
|
||||
option packetsize 1000
|
||||
option avgrate 50
|
||||
option priority 10
|
||||
|
||||
config class "Normal"
|
||||
option packetsize 1500
|
||||
option packetdelay 100
|
||||
option avgrate 10
|
||||
option priority 5
|
||||
config class "Normal_down"
|
||||
option avgrate 20
|
||||
|
||||
config class "Bulk"
|
||||
option avgrate 1
|
||||
option packetdelay 200
|
||||
2
package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos
Executable file
2
package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
[ "$ACTION" = ifup ] && /etc/init.d/qos enabled && /usr/lib/qos/generate.sh interface "$INTERFACE" | sh
|
||||
28
package/network/config/qos-scripts/files/etc/init.d/qos
Executable file
28
package/network/config/qos-scripts/files/etc/init.d/qos
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
|
||||
START=50
|
||||
USE_PROCD=1
|
||||
|
||||
validate_qos_section()
|
||||
{
|
||||
uci_validate_section qos interface "${1}" \
|
||||
'enabled:bool' \
|
||||
'upload:uinteger' \
|
||||
'download:uinteger'
|
||||
}
|
||||
|
||||
service_triggers()
|
||||
{
|
||||
procd_add_reload_trigger "qos"
|
||||
procd_add_validation validate_qos_section
|
||||
qos-start
|
||||
}
|
||||
|
||||
start_service() {
|
||||
qos-start
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
qos-start
|
||||
}
|
||||
4
package/network/config/qos-scripts/files/usr/bin/qos-start
Executable file
4
package/network/config/qos-scripts/files/usr/bin/qos-start
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
qos-stop
|
||||
/usr/lib/qos/generate.sh all | sh
|
||||
|
||||
68
package/network/config/qos-scripts/files/usr/bin/qos-stat
Executable file
68
package/network/config/qos-scripts/files/usr/bin/qos-stat
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2011 OpenWrt.org
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
include /lib/network
|
||||
|
||||
get_ifname() {
|
||||
local interface="$1"
|
||||
local cfgt
|
||||
|
||||
scan_interfaces
|
||||
config_get cfgt "$interface" TYPE
|
||||
[ "$cfgt" = "interface" ] && config_get "$interface" ifname
|
||||
}
|
||||
|
||||
qos_set_device() {
|
||||
config_get TYPE "$1" TYPE
|
||||
[ "interface" = "$TYPE" ] && {
|
||||
config_get device "$1" ifname
|
||||
[ -z "$device" ] && device="$(get_ifname $1)"
|
||||
config_set "$1" device "$device"
|
||||
}
|
||||
}
|
||||
|
||||
config_load qos
|
||||
config_foreach qos_set_device
|
||||
|
||||
print_comments() {
|
||||
echo ''
|
||||
echo '# Interface: '"$1"
|
||||
echo '# Direction: '"$2"
|
||||
echo '# Stats: '"$3"
|
||||
echo ''
|
||||
}
|
||||
|
||||
get_device() {
|
||||
( config_load network; scan_interfaces; config_get "$1" ifname )
|
||||
}
|
||||
|
||||
interface_stats() {
|
||||
local interface="$1"
|
||||
local device
|
||||
|
||||
device="$(get_device "$interface")"
|
||||
[ -z "$device" ] && config_get device "$interface" device
|
||||
config_get_bool enabled "$interface" enabled 1
|
||||
[ -z "$device" -o 1 -ne "$enabled" ] && {
|
||||
return 1
|
||||
}
|
||||
config_get_bool halfduplex "$interface" halfduplex 0
|
||||
|
||||
if [ 1 -ne "$halfduplex" ]; then
|
||||
unset halfduplex
|
||||
print_comments "$interface" "Egress" "Start"
|
||||
tc -s class show dev "$device"
|
||||
print_comments "$interface" "Egress" "End"
|
||||
id="root"
|
||||
else
|
||||
id=""
|
||||
fi
|
||||
|
||||
print_comments "$interface" "Ingress${halfduplex:+/Egress}" "Start"
|
||||
tc -s class show dev "$(tc filter show dev $device $id | grep mirred | sed -e 's,.*\(ifb.*\)).*,\1,')"
|
||||
print_comments "$interface" "Ingress${halfduplex:+/Egress}" "End"
|
||||
}
|
||||
|
||||
[ -z "$1" ] && config_foreach interface_stats interface || interface_stats "$1"
|
||||
6
package/network/config/qos-scripts/files/usr/bin/qos-stop
Executable file
6
package/network/config/qos-scripts/files/usr/bin/qos-stop
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
for iface in $(tc qdisc show | grep -E '(hfsc|ingress)' | awk '{print $5}'); do
|
||||
tc qdisc del dev "$iface" ingress 2>&- >&-
|
||||
tc qdisc del dev "$iface" root 2>&- >&-
|
||||
done
|
||||
/usr/lib/qos/generate.sh firewall stop | sh
|
||||
536
package/network/config/qos-scripts/files/usr/lib/qos/generate.sh
Executable file
536
package/network/config/qos-scripts/files/usr/lib/qos/generate.sh
Executable file
@@ -0,0 +1,536 @@
|
||||
#!/bin/sh
|
||||
[ -e /lib/functions.sh ] && . /lib/functions.sh || . ./functions.sh
|
||||
[ -x /sbin/modprobe ] && {
|
||||
insmod="modprobe"
|
||||
rmmod="$insmod -r"
|
||||
} || {
|
||||
insmod="insmod"
|
||||
rmmod="rmmod"
|
||||
}
|
||||
|
||||
add_insmod() {
|
||||
eval "export isset=\${insmod_$1}"
|
||||
case "$isset" in
|
||||
1) ;;
|
||||
*) {
|
||||
[ "$2" ] && append INSMOD "$rmmod $1 >&- 2>&-" "$N"
|
||||
append INSMOD "$insmod $* >&- 2>&-" "$N"; export insmod_$1=1
|
||||
};;
|
||||
esac
|
||||
}
|
||||
|
||||
[ -e /etc/config/network ] && {
|
||||
# only try to parse network config on openwrt
|
||||
|
||||
find_ifname() {(
|
||||
reset_cb
|
||||
include /lib/network
|
||||
scan_interfaces
|
||||
config_get "$1" ifname
|
||||
)}
|
||||
} || {
|
||||
find_ifname() {
|
||||
echo "Interface not found."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
parse_matching_rule() {
|
||||
local var="$1"
|
||||
local section="$2"
|
||||
local options="$3"
|
||||
local prefix="$4"
|
||||
local suffix="$5"
|
||||
local proto="$6"
|
||||
local mport=""
|
||||
local ports=""
|
||||
|
||||
append "$var" "$prefix" "$N"
|
||||
for option in $options; do
|
||||
case "$option" in
|
||||
proto) config_get value "$section" proto; proto="${proto:-$value}";;
|
||||
esac
|
||||
done
|
||||
config_get type "$section" TYPE
|
||||
case "$type" in
|
||||
classify) unset pkt; append "$var" "-m mark --mark 0/0x0f";;
|
||||
default) pkt=1; append "$var" "-m mark --mark 0/0xf0";;
|
||||
reclassify) pkt=1;;
|
||||
esac
|
||||
append "$var" "${proto:+-p $proto}"
|
||||
for option in $options; do
|
||||
config_get value "$section" "$option"
|
||||
|
||||
case "$pkt:$option" in
|
||||
*:srchost)
|
||||
append "$var" "-s $value"
|
||||
;;
|
||||
*:dsthost)
|
||||
append "$var" "-d $value"
|
||||
;;
|
||||
*:ports|*:srcports|*:dstports)
|
||||
value="$(echo "$value" | sed -e 's,-,:,g')"
|
||||
lproto=${lproto:-tcp}
|
||||
case "$proto" in
|
||||
""|tcp|udp) append "$var" "-m ${proto:-tcp -p tcp} -m multiport";;
|
||||
*) unset "$var"; return 0;;
|
||||
esac
|
||||
case "$option" in
|
||||
ports)
|
||||
config_set "$section" srcports ""
|
||||
config_set "$section" dstports ""
|
||||
config_set "$section" portrange ""
|
||||
append "$var" "--ports $value"
|
||||
;;
|
||||
srcports)
|
||||
config_set "$section" ports ""
|
||||
config_set "$section" dstports ""
|
||||
config_set "$section" portrange ""
|
||||
append "$var" "--sports $value"
|
||||
;;
|
||||
dstports)
|
||||
config_set "$section" ports ""
|
||||
config_set "$section" srcports ""
|
||||
config_set "$section" portrange ""
|
||||
append "$var" "--dports $value"
|
||||
;;
|
||||
esac
|
||||
ports=1
|
||||
;;
|
||||
*:portrange)
|
||||
config_set "$section" ports ""
|
||||
config_set "$section" srcports ""
|
||||
config_set "$section" dstports ""
|
||||
value="$(echo "$value" | sed -e 's,-,:,g')"
|
||||
case "$proto" in
|
||||
""|tcp|udp) append "$var" "-m ${proto:-tcp -p tcp} --sport $value --dport $value";;
|
||||
*) unset "$var"; return 0;;
|
||||
esac
|
||||
ports=1
|
||||
;;
|
||||
*:connbytes)
|
||||
value="$(echo "$value" | sed -e 's,-,:,g')"
|
||||
add_insmod xt_connbytes
|
||||
append "$var" "-m connbytes --connbytes $value --connbytes-dir both --connbytes-mode bytes"
|
||||
;;
|
||||
*:comment)
|
||||
add_insmod xt_comment
|
||||
append "$var" "-m comment --comment '$value'"
|
||||
;;
|
||||
*:tos)
|
||||
add_insmod xt_dscp
|
||||
case "$value" in
|
||||
!*) append "$var" "-m tos ! --tos $value";;
|
||||
*) append "$var" "-m tos --tos $value"
|
||||
esac
|
||||
;;
|
||||
*:dscp)
|
||||
add_insmod xt_dscp
|
||||
dscp_option="--dscp"
|
||||
[ -z "${value%%[EBCA]*}" ] && dscp_option="--dscp-class"
|
||||
case "$value" in
|
||||
!*) append "$var" "-m dscp ! $dscp_option $value";;
|
||||
*) append "$var" "-m dscp $dscp_option $value"
|
||||
esac
|
||||
;;
|
||||
*:direction)
|
||||
value="$(echo "$value" | sed -e 's,-,:,g')"
|
||||
if [ "$value" = "out" ]; then
|
||||
append "$var" "-o $device"
|
||||
elif [ "$value" = "in" ]; then
|
||||
append "$var" "-i $device"
|
||||
fi
|
||||
;;
|
||||
*:srciface)
|
||||
append "$var" "-i $value"
|
||||
;;
|
||||
1:pktsize)
|
||||
value="$(echo "$value" | sed -e 's,-,:,g')"
|
||||
add_insmod xt_length
|
||||
append "$var" "-m length --length $value"
|
||||
;;
|
||||
1:limit)
|
||||
add_insmod xt_limit
|
||||
append "$var" "-m limit --limit $value"
|
||||
;;
|
||||
1:tcpflags)
|
||||
case "$proto" in
|
||||
tcp) append "$var" "-m tcp --tcp-flags ALL $value";;
|
||||
*) unset $var; return 0;;
|
||||
esac
|
||||
;;
|
||||
1:mark)
|
||||
config_get class "${value##!}" classnr
|
||||
[ -z "$class" ] && continue;
|
||||
case "$value" in
|
||||
!*) append "$var" "-m mark ! --mark $class/0x0f";;
|
||||
*) append "$var" "-m mark --mark $class/0x0f";;
|
||||
esac
|
||||
;;
|
||||
1:TOS)
|
||||
add_insmod xt_DSCP
|
||||
config_get TOS "$rule" 'TOS'
|
||||
suffix="-j TOS --set-tos "${TOS:-"Normal-Service"}
|
||||
;;
|
||||
1:DSCP)
|
||||
add_insmod xt_DSCP
|
||||
config_get DSCP "$rule" 'DSCP'
|
||||
[ -z "${DSCP%%[EBCA]*}" ] && set_value="--set-dscp-class $DSCP" \
|
||||
|| set_value="--set-dscp $DSCP"
|
||||
suffix="-j DSCP $set_value"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
append "$var" "$suffix"
|
||||
case "$ports:$proto" in
|
||||
1:) parse_matching_rule "$var" "$section" "$options" "$prefix" "$suffix" "udp";;
|
||||
esac
|
||||
}
|
||||
|
||||
config_cb() {
|
||||
option_cb() {
|
||||
return 0
|
||||
}
|
||||
case "$1" in
|
||||
interface)
|
||||
config_set "$2" "classgroup" "Default"
|
||||
config_set "$2" "upload" "128"
|
||||
;;
|
||||
classify|default|reclassify)
|
||||
option_cb() {
|
||||
append "CONFIG_${CONFIG_SECTION}_options" "$1"
|
||||
}
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
qos_parse_config() {
|
||||
config_get TYPE "$1" TYPE
|
||||
case "$TYPE" in
|
||||
interface)
|
||||
config_get_bool enabled "$1" enabled 1
|
||||
[ 1 -eq "$enabled" ] && {
|
||||
config_get classgroup "$1" classgroup
|
||||
config_set "$1" ifbdev "$C"
|
||||
C=$(($C+1))
|
||||
append INTERFACES "$1"
|
||||
config_set "$classgroup" enabled 1
|
||||
config_get device "$1" device
|
||||
[ -z "$device" ] && {
|
||||
device="$(find_ifname $1)"
|
||||
config_set "$1" device "$device"
|
||||
}
|
||||
}
|
||||
;;
|
||||
classgroup) append CG "$1";;
|
||||
classify|default|reclassify)
|
||||
case "$TYPE" in
|
||||
classify) var="ctrules";;
|
||||
*) var="rules";;
|
||||
esac
|
||||
append "$var" "$1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
enum_classes() {
|
||||
local c="0"
|
||||
config_get classes "$1" classes
|
||||
config_get default "$1" default
|
||||
for class in $classes; do
|
||||
c="$(($c + 1))"
|
||||
config_set "${class}" classnr $c
|
||||
case "$class" in
|
||||
$default) class_default=$c;;
|
||||
esac
|
||||
done
|
||||
class_default="${class_default:-$c}"
|
||||
}
|
||||
|
||||
cls_var() {
|
||||
local varname="$1"
|
||||
local class="$2"
|
||||
local name="$3"
|
||||
local type="$4"
|
||||
local default="$5"
|
||||
local tmp tmp1 tmp2
|
||||
config_get tmp1 "$class" "$name"
|
||||
config_get tmp2 "${class}_${type}" "$name"
|
||||
tmp="${tmp2:-$tmp1}"
|
||||
tmp="${tmp:-$tmp2}"
|
||||
export ${varname}="${tmp:-$default}"
|
||||
}
|
||||
|
||||
tcrules() {
|
||||
_dir=/usr/lib/qos
|
||||
[ -e $_dir/tcrules.awk ] || _dir=.
|
||||
echo "$cstr" | awk \
|
||||
-v device="$dev" \
|
||||
-v linespeed="$rate" \
|
||||
-v direction="$dir" \
|
||||
-f $_dir/tcrules.awk
|
||||
}
|
||||
|
||||
start_interface() {
|
||||
local iface="$1"
|
||||
local num_ifb="$2"
|
||||
config_get device "$iface" device
|
||||
config_get_bool enabled "$iface" enabled 1
|
||||
[ -z "$device" -o 1 -ne "$enabled" ] && {
|
||||
return 1
|
||||
}
|
||||
config_get upload "$iface" upload
|
||||
config_get_bool halfduplex "$iface" halfduplex
|
||||
config_get download "$iface" download
|
||||
config_get classgroup "$iface" classgroup
|
||||
config_get_bool overhead "$iface" overhead 0
|
||||
|
||||
download="${download:-${halfduplex:+$upload}}"
|
||||
enum_classes "$classgroup"
|
||||
for dir in ${halfduplex:-up} ${download:+down}; do
|
||||
case "$dir" in
|
||||
up)
|
||||
[ "$overhead" = 1 ] && upload=$(($upload * 98 / 100 - (15 * 128 / $upload)))
|
||||
dev="$device"
|
||||
rate="$upload"
|
||||
dl_mode=""
|
||||
prefix="cls"
|
||||
;;
|
||||
down)
|
||||
[ "$(ls -d /proc/sys/net/ipv4/conf/ifb* 2>&- | wc -l)" -ne "$num_ifb" ] && add_insmod ifb numifbs="$num_ifb"
|
||||
config_get ifbdev "$iface" ifbdev
|
||||
[ "$overhead" = 1 ] && download=$(($download * 98 / 100 - (80 * 1024 / $download)))
|
||||
dev="ifb$ifbdev"
|
||||
rate="$download"
|
||||
dl_mode=1
|
||||
prefix="d_cls"
|
||||
;;
|
||||
*) continue;;
|
||||
esac
|
||||
cstr=
|
||||
for class in $classes; do
|
||||
cls_var pktsize "$class" packetsize $dir 1500
|
||||
cls_var pktdelay "$class" packetdelay $dir 0
|
||||
cls_var maxrate "$class" limitrate $dir 100
|
||||
cls_var prio "$class" priority $dir 1
|
||||
cls_var avgrate "$class" avgrate $dir 0
|
||||
cls_var qdisc "$class" qdisc $dir ""
|
||||
cls_var filter "$class" filter $dir ""
|
||||
config_get classnr "$class" classnr
|
||||
append cstr "$classnr:$prio:$avgrate:$pktsize:$pktdelay:$maxrate:$qdisc:$filter" "$N"
|
||||
done
|
||||
append ${prefix}q "$(tcrules)" "$N"
|
||||
export dev_${dir}="ifconfig $dev up >&- 2>&-
|
||||
tc qdisc del dev $dev root >&- 2>&-
|
||||
tc qdisc add dev $dev root handle 1: hfsc default ${class_default}0
|
||||
tc class add dev $dev parent 1: classid 1:1 hfsc sc rate ${rate}kbit ul rate ${rate}kbit"
|
||||
done
|
||||
[ -n "$download" ] && {
|
||||
add_insmod cls_u32
|
||||
add_insmod em_u32
|
||||
add_insmod act_connmark
|
||||
add_insmod act_mirred
|
||||
add_insmod sch_ingress
|
||||
}
|
||||
if [ -n "$halfduplex" ]; then
|
||||
export dev_up="tc qdisc del dev $device root >&- 2>&-
|
||||
tc qdisc add dev $device root handle 1: hfsc
|
||||
tc filter add dev $device parent 1: prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb$ifbdev"
|
||||
elif [ -n "$download" ]; then
|
||||
append dev_${dir} "tc qdisc del dev $device ingress >&- 2>&-
|
||||
tc qdisc add dev $device ingress
|
||||
tc filter add dev $device parent ffff: prio 1 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb$ifbdev" "$N"
|
||||
fi
|
||||
add_insmod cls_fw
|
||||
add_insmod sch_hfsc
|
||||
|
||||
cat <<EOF
|
||||
${INSMOD:+$INSMOD$N}${dev_up:+$dev_up
|
||||
$clsq
|
||||
}${ifbdev:+$dev_down
|
||||
$d_clsq
|
||||
$d_clsl
|
||||
$d_clsf
|
||||
}
|
||||
EOF
|
||||
unset INSMOD clsq clsf clsl d_clsq d_clsl d_clsf dev_up dev_down
|
||||
}
|
||||
|
||||
start_interfaces() {
|
||||
local C="$1"
|
||||
for iface in $INTERFACES; do
|
||||
start_interface "$iface" "$C"
|
||||
done
|
||||
}
|
||||
|
||||
add_rules() {
|
||||
local var="$1"
|
||||
local rules="$2"
|
||||
local prefix="$3"
|
||||
|
||||
for rule in $rules; do
|
||||
unset iptrule
|
||||
config_get target "$rule" target
|
||||
config_get target "$target" classnr
|
||||
config_get options "$rule" options
|
||||
|
||||
## If we want to override the TOS field, let's clear the DSCP field first.
|
||||
[ ! -z "$(echo $options | grep 'TOS')" ] && {
|
||||
s_options=${options%%TOS}
|
||||
add_insmod xt_DSCP
|
||||
parse_matching_rule iptrule "$rule" "$s_options" "$prefix" "-j DSCP --set-dscp 0"
|
||||
append "$var" "$iptrule" "$N"
|
||||
unset iptrule
|
||||
}
|
||||
|
||||
target=$(($target | ($target << 4)))
|
||||
parse_matching_rule iptrule "$rule" "$options" "$prefix" "-j MARK --set-mark $target/0xff"
|
||||
append "$var" "$iptrule" "$N"
|
||||
done
|
||||
}
|
||||
|
||||
start_cg() {
|
||||
local cg="$1"
|
||||
local iptrules
|
||||
local pktrules
|
||||
local sizerules
|
||||
enum_classes "$cg"
|
||||
for command in $iptables; do
|
||||
add_rules iptrules "$ctrules" "$command -w -t mangle -A qos_${cg}_ct"
|
||||
done
|
||||
config_get classes "$cg" classes
|
||||
for class in $classes; do
|
||||
config_get mark "$class" classnr
|
||||
config_get maxsize "$class" maxsize
|
||||
[ -z "$maxsize" -o -z "$mark" ] || {
|
||||
add_insmod xt_length
|
||||
for command in $iptables; do
|
||||
append pktrules "$command -w -t mangle -A qos_${cg} -m mark --mark $mark/0x0f -m length --length $maxsize: -j MARK --set-mark 0/0xff" "$N"
|
||||
done
|
||||
}
|
||||
done
|
||||
for command in $iptables; do
|
||||
add_rules pktrules "$rules" "$command -w -t mangle -A qos_${cg}"
|
||||
done
|
||||
for iface in $INTERFACES; do
|
||||
config_get classgroup "$iface" classgroup
|
||||
config_get device "$iface" device
|
||||
config_get ifbdev "$iface" ifbdev
|
||||
config_get upload "$iface" upload
|
||||
config_get download "$iface" download
|
||||
config_get halfduplex "$iface" halfduplex
|
||||
download="${download:-${halfduplex:+$upload}}"
|
||||
for command in $iptables; do
|
||||
append up "$command -w -t mangle -A OUTPUT -o $device -j qos_${cg}" "$N"
|
||||
append up "$command -w -t mangle -A FORWARD -o $device -j qos_${cg}" "$N"
|
||||
done
|
||||
done
|
||||
cat <<EOF
|
||||
$INSMOD
|
||||
EOF
|
||||
|
||||
for command in $iptables; do
|
||||
cat <<EOF
|
||||
$command -w -t mangle -N qos_${cg}
|
||||
$command -w -t mangle -N qos_${cg}_ct
|
||||
EOF
|
||||
done
|
||||
cat <<EOF
|
||||
${iptrules:+${iptrules}${N}}
|
||||
EOF
|
||||
for command in $iptables; do
|
||||
cat <<EOF
|
||||
$command -w -t mangle -A qos_${cg}_ct -j CONNMARK --save-mark --mask 0xff
|
||||
$command -w -t mangle -A qos_${cg} -j CONNMARK --restore-mark --mask 0x0f
|
||||
$command -w -t mangle -A qos_${cg} -m mark --mark 0/0x0f -j qos_${cg}_ct
|
||||
EOF
|
||||
done
|
||||
cat <<EOF
|
||||
$pktrules
|
||||
EOF
|
||||
for command in $iptables; do
|
||||
cat <<EOF
|
||||
$command -w -t mangle -A qos_${cg} -j CONNMARK --save-mark --mask 0xff
|
||||
EOF
|
||||
done
|
||||
cat <<EOF
|
||||
$up$N${down:+${down}$N}
|
||||
EOF
|
||||
unset INSMOD
|
||||
}
|
||||
|
||||
start_firewall() {
|
||||
add_insmod xt_multiport
|
||||
add_insmod xt_connmark
|
||||
stop_firewall
|
||||
for group in $CG; do
|
||||
start_cg $group
|
||||
done
|
||||
}
|
||||
|
||||
stop_firewall() {
|
||||
# Builds up a list of iptables commands to flush the qos_* chains,
|
||||
# remove rules referring to them, then delete them
|
||||
|
||||
# Print rules in the mangle table, like iptables-save
|
||||
for command in $iptables; do
|
||||
$command -w -t mangle -S |
|
||||
# Find rules for the qos_* chains
|
||||
grep -E '(^-N qos_|-j qos_)' |
|
||||
# Exclude rules in qos_* chains (inter-qos_* refs)
|
||||
grep -v '^-A qos_' |
|
||||
# Replace -N with -X and hold, with -F and print
|
||||
# Replace -A with -D
|
||||
# Print held lines at the end (note leading newline)
|
||||
sed -e '/^-N/{s/^-N/-X/;H;s/^-X/-F/}' \
|
||||
-e 's/^-A/-D/' \
|
||||
-e '${p;g}' |
|
||||
# Make into proper iptables calls
|
||||
# Note: awkward in previous call due to hold space usage
|
||||
sed -n -e "s/^./${command} -w -t mangle &/p"
|
||||
done
|
||||
}
|
||||
|
||||
C="0"
|
||||
INTERFACES=""
|
||||
[ -e ./qos.conf ] && {
|
||||
. ./qos.conf
|
||||
config_cb
|
||||
} || {
|
||||
config_load qos
|
||||
config_foreach qos_parse_config
|
||||
}
|
||||
|
||||
C="0"
|
||||
for iface in $INTERFACES; do
|
||||
export C="$(($C + 1))"
|
||||
done
|
||||
|
||||
[ -x /usr/sbin/ip6tables ] && {
|
||||
iptables="ip6tables iptables"
|
||||
} || {
|
||||
iptables="iptables"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
all)
|
||||
start_interfaces "$C"
|
||||
start_firewall
|
||||
;;
|
||||
interface)
|
||||
start_interface "$2" "$C"
|
||||
;;
|
||||
interfaces)
|
||||
start_interfaces
|
||||
;;
|
||||
firewall)
|
||||
case "$2" in
|
||||
stop)
|
||||
stop_firewall
|
||||
;;
|
||||
start|"")
|
||||
start_firewall
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
106
package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk
Normal file
106
package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk
Normal file
@@ -0,0 +1,106 @@
|
||||
BEGIN {
|
||||
dmax=100
|
||||
if (!(linespeed > 0)) linespeed = 128
|
||||
FS=":"
|
||||
n = 0
|
||||
}
|
||||
|
||||
($1 != "") {
|
||||
n++
|
||||
class[n] = $1
|
||||
prio[n] = $2
|
||||
avgrate[n] = ($3 * linespeed / 100)
|
||||
pktsize[n] = $4
|
||||
delay[n] = $5
|
||||
maxrate[n] = ($6 * linespeed / 100)
|
||||
qdisc[n] = $7
|
||||
filter[n] = $8
|
||||
}
|
||||
|
||||
END {
|
||||
allocated = 0
|
||||
maxdelay = 0
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
# set defaults
|
||||
if (!(pktsize[i] > 0)) pktsize[i] = 1500
|
||||
if (!(prio[i] > 0)) prio[i] = 1
|
||||
|
||||
allocated += avgrate[i]
|
||||
sum_prio += prio[i]
|
||||
if ((avgrate[i] > 0) && !(delay[i] > 0)) {
|
||||
sum_rtprio += prio[i]
|
||||
}
|
||||
}
|
||||
|
||||
# allocation of m1 in rt classes:
|
||||
# sum(d * m1) must not exceed dmax * (linespeed - allocated)
|
||||
dmax = 0
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (avgrate[i] > 0) {
|
||||
rtm2[i] = avgrate[i]
|
||||
if (delay[i] > 0) {
|
||||
d[i] = delay[i]
|
||||
} else {
|
||||
d[i] = 2 * pktsize[i] * 1000 / (linespeed * 1024)
|
||||
if (d[i] > dmax) dmax = d[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ds_avail = dmax * (linespeed - allocated)
|
||||
for (i = 1; i <= n; i++) {
|
||||
lsm1[i] = 0
|
||||
rtm1[i] = 0
|
||||
lsm2[i] = linespeed * prio[i] / sum_prio
|
||||
if ((avgrate[i] > 0) && (d[i] > 0)) {
|
||||
if (!(delay[i] > 0)) {
|
||||
ds = ds_avail * prio[i] / sum_rtprio
|
||||
ds_avail -= ds
|
||||
rtm1[i] = rtm2[i] + ds/d[i]
|
||||
}
|
||||
lsm1[i] = rtm1[i]
|
||||
}
|
||||
else {
|
||||
d[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
# main qdisc
|
||||
for (i = 1; i <= n; i++) {
|
||||
printf "tc class add dev "device" parent 1:1 classid 1:"class[i]"0 hfsc"
|
||||
if (rtm1[i] > 0) {
|
||||
printf " rt m1 " int(rtm1[i]) "kbit d " int(d[i] * 1000) "us m2 " int(rtm2[i])"kbit"
|
||||
}
|
||||
printf " ls m1 " int(lsm1[i]) "kbit d " int(d[i] * 1000) "us m2 " int(lsm2[i]) "kbit"
|
||||
print " ul rate " int(maxrate[i]) "kbit"
|
||||
}
|
||||
|
||||
# leaf qdisc
|
||||
avpkt = 1200
|
||||
for (i = 1; i <= n; i++) {
|
||||
print "tc qdisc add dev "device" parent 1:"class[i]"0 handle "class[i]"00: fq_codel limit 800 quantum 300 noecn"
|
||||
}
|
||||
|
||||
# filter rule
|
||||
for (i = 1; i <= n; i++) {
|
||||
filter_cmd = "tc filter add dev "device" parent 1: prio %d handle %s fw flowid 1:%d0\n";
|
||||
if (direction == "up") {
|
||||
filter_1 = sprintf("0x%x0/0xf0", class[i])
|
||||
filter_2 = sprintf("0x0%x/0x0f", class[i])
|
||||
} else {
|
||||
filter_1 = sprintf("0x0%x/0x0f", class[i])
|
||||
filter_2 = sprintf("0x%x0/0xf0", class[i])
|
||||
}
|
||||
|
||||
printf filter_cmd, class[i] * 2, filter_1, class[i]
|
||||
printf filter_cmd, class[i] * 2 + 1, filter_2, class[i]
|
||||
|
||||
filterc=1
|
||||
if (filter[i] != "") {
|
||||
print " tc filter add dev "device" parent "class[i]"00: handle "filterc"0 "filter[i]
|
||||
filterc=filterc+1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
45
package/network/config/soloscli/Makefile
Normal file
45
package/network/config/soloscli/Makefile
Normal file
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# Copyright (C) 2006-2014 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=soloscli
|
||||
PKG_VERSION:=1.04
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=solos-pci-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=@SF/openadsl
|
||||
PKG_HASH:=6379e6970a5c97fd5a223d024138ebb71b15d70e2ad1fe9da09edc5b2d760e1d
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/solos-pci-$(PKG_VERSION)
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/soloscli
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Configuration utility for Solos ADSL2+ modems
|
||||
DEPENDS:=+kmod-solos-pci
|
||||
URL:=http://sourceforge.net/projects/openadsl
|
||||
endef
|
||||
|
||||
define Package/soloscli/description
|
||||
This package contains the soloscli utility
|
||||
for interrogating Traverse Technologies' Solos ADSL2+ modems.
|
||||
endef
|
||||
|
||||
define Package/soloscli/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/soloscli/soloscli $(1)/usr/bin/
|
||||
$(INSTALL_BIN) ./files/solos-log-stats $(1)/usr/bin/
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/atm
|
||||
$(INSTALL_DATA) ./files/etc/hotplug.d/atm/15-solos-init $(1)/etc/hotplug.d/atm/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,soloscli))
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
dialog() {
|
||||
local tag="$(echo "$1" | cut -d= -f1)"
|
||||
local value="$(echo "$1" | cut -d= -f2-)"
|
||||
local response
|
||||
|
||||
response="$(soloscli -s "$port" "$tag" "$value")"
|
||||
[ $? -ne 0 ] && {
|
||||
logger "soloscli($port): $tag '$value' returns $response"
|
||||
}
|
||||
}
|
||||
|
||||
if [ "$ACTION" = "add" ]; then
|
||||
include /lib/network
|
||||
scan_interfaces
|
||||
|
||||
case $DEVICENAME in
|
||||
solos-pci[0-3])
|
||||
port="${DEVICENAME#solos-pci}"
|
||||
device="solos${port}"
|
||||
|
||||
config_list_foreach wan "$device" dialog
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
15
package/network/config/soloscli/files/etc/uci-default/solos
Normal file
15
package/network/config/soloscli/files/etc/uci-default/solos
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci batch <<__EOF__
|
||||
|
||||
delete network.wan.solos0
|
||||
|
||||
add_list network.wan.solos0="ActivateLine=Abort"
|
||||
add_list network.wan.solos0="Retrain=EnableAll"
|
||||
add_list network.wan.solos0="DetectNoise=Enable"
|
||||
add_list network.wan.solos0="BisMCapability=Disable"
|
||||
add_list network.wan.solos0="BisACapability=Disable"
|
||||
add_list network.wan.solos0="ActivateLine=Start"
|
||||
|
||||
commit network
|
||||
__EOF__
|
||||
19
package/network/config/soloscli/files/solos-log-stats
Normal file
19
package/network/config/soloscli/files/solos-log-stats
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /sys/class/atm/ || exit 1
|
||||
|
||||
for PORT in solos-pci* ; do
|
||||
|
||||
RXRATE=`cat $PORT/parameters/RxBitRate`
|
||||
TXRATE=`cat $PORT/parameters/TxBitRate`
|
||||
RXSNR=`cat $PORT/parameters/LocalSNRMargin | sed "s/ dB//"`
|
||||
TXSNR=`cat $PORT/parameters/RemoteSNRMargin | sed "s/ dB//"`
|
||||
RXERR=`cat $PORT/parameters/RSUnCorrectedErrorsDn`
|
||||
TXERR=`cat $PORT/parameters/RSUnCorrectedErrorsUp`
|
||||
RXFEC=`cat $PORT/parameters/RSCorrectedErrorsDn`
|
||||
TXFEC=`cat $PORT/parameters/RSCorrectedErrorsUp`
|
||||
|
||||
echo "$RXRATE $RXSNR $RXERR $RXFEC / $TXRATE $TXSNR $TXERR $TXFEC" |
|
||||
logger -t $PORT
|
||||
done
|
||||
|
||||
11
package/network/config/soloscli/patches/001-no-driver.patch
Normal file
11
package/network/config/soloscli/patches/001-no-driver.patch
Normal file
@@ -0,0 +1,11 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -11,7 +11,7 @@ else
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
-all: soloscli driver
|
||||
+all: soloscli
|
||||
|
||||
soloscli: soloscli/soloscli
|
||||
|
||||
12
package/network/config/soloscli/patches/002-cflags.patch
Normal file
12
package/network/config/soloscli/patches/002-cflags.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
--- a/soloscli/Makefile
|
||||
+++ b/soloscli/Makefile
|
||||
@@ -4,9 +4,6 @@
|
||||
# Last Mod: 2009-06-16
|
||||
#
|
||||
|
||||
-CC=gcc
|
||||
-CFLAGS=-Wall
|
||||
-
|
||||
soloscli: soloscli.c soloscli.h
|
||||
|
||||
clean:
|
||||
54
package/network/config/swconfig/Makefile
Normal file
54
package/network/config/swconfig/Makefile
Normal file
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# Copyright (C) 2008-2010 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=swconfig
|
||||
PKG_RELEASE:=11
|
||||
|
||||
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
define Package/swconfig
|
||||
SECTION:=base
|
||||
CATEGORY:=Base system
|
||||
DEPENDS:=+libuci +libnl-tiny
|
||||
TITLE:=Switch configuration utility
|
||||
endef
|
||||
|
||||
TARGET_CPPFLAGS := \
|
||||
-D_GNU_SOURCE \
|
||||
-I$(STAGING_DIR)/usr/include/libnl-tiny \
|
||||
-I$(PKG_BUILD_DIR) \
|
||||
$(TARGET_CPPFLAGS) \
|
||||
-I$(LINUX_DIR)/user_headers/include
|
||||
|
||||
define Build/Compile
|
||||
CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
LIBS="$(TARGET_LDFLAGS) -lnl-tiny -lm -luci -lubox"
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(CP) $(PKG_BUILD_DIR)/swlib.h $(1)/usr/include/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_BUILD_DIR)/libsw.a $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
define Package/swconfig/install
|
||||
$(INSTALL_DIR) $(1)/sbin $(1)/lib/network
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/swconfig $(1)/sbin/swconfig
|
||||
$(INSTALL_DATA) ./files/switch.sh $(1)/lib/network/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,swconfig))
|
||||
15
package/network/config/swconfig/files/switch.sh
Normal file
15
package/network/config/swconfig/files/switch.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2009 OpenWrt.org
|
||||
|
||||
setup_switch_dev() {
|
||||
local name
|
||||
config_get name "$1" name
|
||||
name="${name:-$1}"
|
||||
[ -d "/sys/class/net/$name" ] && ip link set dev "$name" up
|
||||
swconfig dev "$name" load network
|
||||
}
|
||||
|
||||
setup_switch() {
|
||||
config_load network
|
||||
config_foreach setup_switch_dev switch
|
||||
}
|
||||
16
package/network/config/swconfig/src/Makefile
Normal file
16
package/network/config/swconfig/src/Makefile
Normal file
@@ -0,0 +1,16 @@
|
||||
ifndef CFLAGS
|
||||
CFLAGS = -O2 -g -I ../src
|
||||
endif
|
||||
LIBS=-lnl -lnl-genl
|
||||
|
||||
all: swconfig
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -fPIC -c -o $@ $^
|
||||
|
||||
libsw.a: swlib.o
|
||||
$(AR) rcu $@ swlib.o
|
||||
$(RANLIB) $@
|
||||
|
||||
swconfig: libsw.a cli.o uci.o
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) -L./ -lsw
|
||||
387
package/network/config/swconfig/src/cli.c
Normal file
387
package/network/config/swconfig/src/cli.c
Normal file
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
* swconfig.c: Switch configuration utility
|
||||
*
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
* Copyright (C) 2010 Martin Mares <mj@ucw.cz>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundatio.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <uci.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/switch.h>
|
||||
#include "swlib.h"
|
||||
|
||||
enum {
|
||||
CMD_NONE,
|
||||
CMD_GET,
|
||||
CMD_SET,
|
||||
CMD_LOAD,
|
||||
CMD_HELP,
|
||||
CMD_SHOW,
|
||||
CMD_PORTMAP,
|
||||
};
|
||||
|
||||
static void
|
||||
print_attrs(const struct switch_attr *attr)
|
||||
{
|
||||
int i = 0;
|
||||
while (attr) {
|
||||
const char *type;
|
||||
switch(attr->type) {
|
||||
case SWITCH_TYPE_INT:
|
||||
type = "int";
|
||||
break;
|
||||
case SWITCH_TYPE_STRING:
|
||||
type = "string";
|
||||
break;
|
||||
case SWITCH_TYPE_PORTS:
|
||||
type = "ports";
|
||||
break;
|
||||
case SWITCH_TYPE_NOVAL:
|
||||
type = "none";
|
||||
break;
|
||||
default:
|
||||
type = "unknown";
|
||||
break;
|
||||
}
|
||||
printf("\tAttribute %d (%s): %s (%s)\n", ++i, type, attr->name, attr->description);
|
||||
attr = attr->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
list_attributes(struct switch_dev *dev)
|
||||
{
|
||||
printf("%s: %s(%s), ports: %d (cpu @ %d), vlans: %d\n", dev->dev_name, dev->alias, dev->name, dev->ports, dev->cpu_port, dev->vlans);
|
||||
printf(" --switch\n");
|
||||
print_attrs(dev->ops);
|
||||
printf(" --vlan\n");
|
||||
print_attrs(dev->vlan_ops);
|
||||
printf(" --port\n");
|
||||
print_attrs(dev->port_ops);
|
||||
}
|
||||
|
||||
static const char *
|
||||
speed_str(int speed)
|
||||
{
|
||||
switch (speed) {
|
||||
case 10:
|
||||
return "10baseT";
|
||||
case 100:
|
||||
return "100baseT";
|
||||
case 1000:
|
||||
return "1000baseT";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void
|
||||
print_attr_val(const struct switch_attr *attr, const struct switch_val *val)
|
||||
{
|
||||
struct switch_port_link *link;
|
||||
int i;
|
||||
|
||||
switch (attr->type) {
|
||||
case SWITCH_TYPE_INT:
|
||||
printf("%d", val->value.i);
|
||||
break;
|
||||
case SWITCH_TYPE_STRING:
|
||||
printf("%s", val->value.s);
|
||||
break;
|
||||
case SWITCH_TYPE_PORTS:
|
||||
for(i = 0; i < val->len; i++) {
|
||||
printf("%d%s ",
|
||||
val->value.ports[i].id,
|
||||
(val->value.ports[i].flags &
|
||||
SWLIB_PORT_FLAG_TAGGED) ? "t" : "");
|
||||
}
|
||||
break;
|
||||
case SWITCH_TYPE_LINK:
|
||||
link = val->value.link;
|
||||
if (link->link)
|
||||
printf("port:%d link:up speed:%s %s-duplex %s%s%s%s%s",
|
||||
val->port_vlan,
|
||||
speed_str(link->speed),
|
||||
link->duplex ? "full" : "half",
|
||||
link->tx_flow ? "txflow " : "",
|
||||
link->rx_flow ? "rxflow " : "",
|
||||
link->eee & SWLIB_LINK_FLAG_EEE_100BASET ? "eee100 " : "",
|
||||
link->eee & SWLIB_LINK_FLAG_EEE_1000BASET ? "eee1000 " : "",
|
||||
link->aneg ? "auto" : "");
|
||||
else
|
||||
printf("port:%d link:down", val->port_vlan);
|
||||
break;
|
||||
default:
|
||||
printf("?unknown-type?");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_attrs(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val)
|
||||
{
|
||||
while (attr) {
|
||||
if (attr->type != SWITCH_TYPE_NOVAL) {
|
||||
printf("\t%s: ", attr->name);
|
||||
if (swlib_get_attr(dev, attr, val) < 0)
|
||||
printf("???");
|
||||
else
|
||||
print_attr_val(attr, val);
|
||||
putchar('\n');
|
||||
}
|
||||
attr = attr->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
show_global(struct switch_dev *dev)
|
||||
{
|
||||
struct switch_val val;
|
||||
|
||||
printf("Global attributes:\n");
|
||||
show_attrs(dev, dev->ops, &val);
|
||||
}
|
||||
|
||||
static void
|
||||
show_port(struct switch_dev *dev, int port)
|
||||
{
|
||||
struct switch_val val;
|
||||
|
||||
printf("Port %d:\n", port);
|
||||
val.port_vlan = port;
|
||||
show_attrs(dev, dev->port_ops, &val);
|
||||
}
|
||||
|
||||
static void
|
||||
show_vlan(struct switch_dev *dev, int vlan, bool all)
|
||||
{
|
||||
struct switch_val val;
|
||||
struct switch_attr *attr;
|
||||
|
||||
val.port_vlan = vlan;
|
||||
|
||||
if (all) {
|
||||
attr = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, "ports");
|
||||
if (swlib_get_attr(dev, attr, &val) < 0)
|
||||
return;
|
||||
|
||||
if (!val.len)
|
||||
return;
|
||||
}
|
||||
|
||||
printf("VLAN %d:\n", vlan);
|
||||
show_attrs(dev, dev->vlan_ops, &val);
|
||||
}
|
||||
|
||||
static void
|
||||
print_usage(void)
|
||||
{
|
||||
printf("swconfig list\n");
|
||||
printf("swconfig dev <dev> [port <port>|vlan <vlan>] (help|set <key> <value>|get <key>|load <config>|show)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
swconfig_load_uci(struct switch_dev *dev, const char *name)
|
||||
{
|
||||
struct uci_context *ctx;
|
||||
struct uci_package *p = NULL;
|
||||
int ret = -1;
|
||||
|
||||
ctx = uci_alloc_context();
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
uci_load(ctx, name, &p);
|
||||
if (!p) {
|
||||
uci_perror(ctx, "Failed to load config file: ");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = swlib_apply_from_uci(dev, p);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "Failed to apply configuration for switch '%s'\n", dev->dev_name);
|
||||
|
||||
out:
|
||||
uci_free_context(ctx);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int retval = 0;
|
||||
struct switch_dev *dev;
|
||||
struct switch_attr *a;
|
||||
struct switch_val val;
|
||||
int i;
|
||||
|
||||
int cmd = CMD_NONE;
|
||||
char *cdev = NULL;
|
||||
int cport = -1;
|
||||
int cvlan = -1;
|
||||
char *ckey = NULL;
|
||||
char *cvalue = NULL;
|
||||
char *csegment = NULL;
|
||||
|
||||
if((argc == 2) && !strcmp(argv[1], "list")) {
|
||||
swlib_list();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(argc < 4)
|
||||
print_usage();
|
||||
|
||||
if(strcmp(argv[1], "dev"))
|
||||
print_usage();
|
||||
|
||||
cdev = argv[2];
|
||||
|
||||
for(i = 3; i < argc; i++)
|
||||
{
|
||||
char *arg = argv[i];
|
||||
if (cmd != CMD_NONE) {
|
||||
print_usage();
|
||||
} else if (!strcmp(arg, "port") && i+1 < argc) {
|
||||
cport = atoi(argv[++i]);
|
||||
} else if (!strcmp(arg, "vlan") && i+1 < argc) {
|
||||
cvlan = atoi(argv[++i]);
|
||||
} else if (!strcmp(arg, "help")) {
|
||||
cmd = CMD_HELP;
|
||||
} else if (!strcmp(arg, "set") && i+1 < argc) {
|
||||
cmd = CMD_SET;
|
||||
ckey = argv[++i];
|
||||
if (i+1 < argc)
|
||||
cvalue = argv[++i];
|
||||
} else if (!strcmp(arg, "get") && i+1 < argc) {
|
||||
cmd = CMD_GET;
|
||||
ckey = argv[++i];
|
||||
} else if (!strcmp(arg, "load") && i+1 < argc) {
|
||||
if ((cport >= 0) || (cvlan >= 0))
|
||||
print_usage();
|
||||
cmd = CMD_LOAD;
|
||||
ckey = argv[++i];
|
||||
} else if (!strcmp(arg, "portmap")) {
|
||||
if (i + 1 < argc)
|
||||
csegment = argv[++i];
|
||||
cmd = CMD_PORTMAP;
|
||||
} else if (!strcmp(arg, "show")) {
|
||||
cmd = CMD_SHOW;
|
||||
} else {
|
||||
print_usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == CMD_NONE)
|
||||
print_usage();
|
||||
if (cport > -1 && cvlan > -1)
|
||||
print_usage();
|
||||
|
||||
dev = swlib_connect(cdev);
|
||||
if (!dev) {
|
||||
fprintf(stderr, "Failed to connect to the switch. Use the \"list\" command to see which switches are available.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
swlib_scan(dev);
|
||||
|
||||
if (cmd == CMD_GET || cmd == CMD_SET) {
|
||||
if(cport > -1)
|
||||
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_PORT, ckey);
|
||||
else if(cvlan > -1)
|
||||
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_VLAN, ckey);
|
||||
else
|
||||
a = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, ckey);
|
||||
|
||||
if(!a)
|
||||
{
|
||||
fprintf(stderr, "Unknown attribute \"%s\"\n", ckey);
|
||||
retval = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case CMD_SET:
|
||||
if ((a->type != SWITCH_TYPE_NOVAL) &&
|
||||
(cvalue == NULL))
|
||||
print_usage();
|
||||
|
||||
if(cvlan > -1)
|
||||
cport = cvlan;
|
||||
|
||||
retval = swlib_set_attr_string(dev, a, cport, cvalue);
|
||||
if (retval < 0)
|
||||
{
|
||||
nl_perror(-retval, "Failed to set attribute");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
case CMD_GET:
|
||||
if(cvlan > -1)
|
||||
val.port_vlan = cvlan;
|
||||
if(cport > -1)
|
||||
val.port_vlan = cport;
|
||||
retval = swlib_get_attr(dev, a, &val);
|
||||
if (retval < 0)
|
||||
{
|
||||
nl_perror(-retval, "Failed to get attribute");
|
||||
goto out;
|
||||
}
|
||||
print_attr_val(a, &val);
|
||||
putchar('\n');
|
||||
break;
|
||||
case CMD_LOAD:
|
||||
swconfig_load_uci(dev, ckey);
|
||||
break;
|
||||
case CMD_HELP:
|
||||
list_attributes(dev);
|
||||
break;
|
||||
case CMD_PORTMAP:
|
||||
swlib_print_portmap(dev, csegment);
|
||||
break;
|
||||
case CMD_SHOW:
|
||||
if (cport >= 0 || cvlan >= 0) {
|
||||
if (cport >= 0)
|
||||
show_port(dev, cport);
|
||||
else
|
||||
show_vlan(dev, cvlan, false);
|
||||
} else {
|
||||
show_global(dev);
|
||||
for (i=0; i < dev->ports; i++)
|
||||
show_port(dev, i);
|
||||
for (i=0; i < dev->vlans; i++)
|
||||
show_vlan(dev, i, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
swlib_free_all(dev);
|
||||
return retval;
|
||||
}
|
||||
923
package/network/config/swconfig/src/swlib.c
Normal file
923
package/network/config/swconfig/src/swlib.c
Normal file
@@ -0,0 +1,923 @@
|
||||
/*
|
||||
* swlib.c: Switch configuration API (user space part)
|
||||
*
|
||||
* Copyright (C) 2008 Felix Fietkau <nbd@nbd.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/switch.h>
|
||||
#include "swlib.h"
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
|
||||
//#define DEBUG 1
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(fmt, ...) fprintf(stderr, "%s(%d): " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
||||
#else
|
||||
#define DPRINTF(fmt, ...) do {} while (0)
|
||||
#endif
|
||||
|
||||
static struct nl_sock *handle;
|
||||
static struct nl_cache *cache;
|
||||
static struct genl_family *family;
|
||||
static struct nlattr *tb[SWITCH_ATTR_MAX + 1];
|
||||
static int refcount = 0;
|
||||
|
||||
static struct nla_policy port_policy[SWITCH_ATTR_MAX] = {
|
||||
[SWITCH_PORT_ID] = { .type = NLA_U32 },
|
||||
[SWITCH_PORT_FLAG_TAGGED] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
static struct nla_policy portmap_policy[SWITCH_PORTMAP_MAX] = {
|
||||
[SWITCH_PORTMAP_SEGMENT] = { .type = NLA_STRING },
|
||||
[SWITCH_PORTMAP_VIRT] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static struct nla_policy link_policy[SWITCH_LINK_ATTR_MAX] = {
|
||||
[SWITCH_LINK_FLAG_LINK] = { .type = NLA_FLAG },
|
||||
[SWITCH_LINK_FLAG_DUPLEX] = { .type = NLA_FLAG },
|
||||
[SWITCH_LINK_FLAG_ANEG] = { .type = NLA_FLAG },
|
||||
[SWITCH_LINK_SPEED] = { .type = NLA_U32 },
|
||||
[SWITCH_LINK_FLAG_EEE_100BASET] = { .type = NLA_FLAG },
|
||||
[SWITCH_LINK_FLAG_EEE_1000BASET] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
static inline void *
|
||||
swlib_alloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ptr = malloc(size);
|
||||
if (!ptr)
|
||||
goto done;
|
||||
memset(ptr, 0, size);
|
||||
|
||||
done:
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int
|
||||
wait_handler(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
int *finished = arg;
|
||||
|
||||
*finished = 1;
|
||||
return NL_STOP;
|
||||
}
|
||||
|
||||
/* helper function for performing netlink requests */
|
||||
static int
|
||||
swlib_call(int cmd, int (*call)(struct nl_msg *, void *),
|
||||
int (*data)(struct nl_msg *, void *), void *arg)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
struct nl_cb *cb = NULL;
|
||||
int finished;
|
||||
int flags = 0;
|
||||
int err = 0;
|
||||
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg) {
|
||||
fprintf(stderr, "Out of memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!data)
|
||||
flags |= NLM_F_DUMP;
|
||||
|
||||
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, genl_family_get_id(family), 0, flags, cmd, 0);
|
||||
if (data) {
|
||||
err = data(msg, arg);
|
||||
if (err < 0)
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
cb = nl_cb_alloc(NL_CB_CUSTOM);
|
||||
if (!cb) {
|
||||
fprintf(stderr, "nl_cb_alloc failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
err = nl_send_auto_complete(handle, msg);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "nl_send_auto_complete failed: %d\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
finished = 0;
|
||||
|
||||
if (call)
|
||||
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, call, arg);
|
||||
|
||||
if (data)
|
||||
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
|
||||
else
|
||||
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &finished);
|
||||
|
||||
err = nl_recvmsgs(handle, cb);
|
||||
if (err < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!finished)
|
||||
err = nl_wait_for_ack(handle);
|
||||
|
||||
out:
|
||||
if (cb)
|
||||
nl_cb_put(cb);
|
||||
nla_put_failure:
|
||||
nlmsg_free(msg);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
send_attr(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct switch_val *val = arg;
|
||||
struct switch_attr *attr = val->attr;
|
||||
|
||||
NLA_PUT_U32(msg, SWITCH_ATTR_ID, attr->dev->id);
|
||||
NLA_PUT_U32(msg, SWITCH_ATTR_OP_ID, attr->id);
|
||||
switch(attr->atype) {
|
||||
case SWLIB_ATTR_GROUP_PORT:
|
||||
NLA_PUT_U32(msg, SWITCH_ATTR_OP_PORT, val->port_vlan);
|
||||
break;
|
||||
case SWLIB_ATTR_GROUP_VLAN:
|
||||
NLA_PUT_U32(msg, SWITCH_ATTR_OP_VLAN, val->port_vlan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
store_port_val(struct nl_msg *msg, struct nlattr *nla, struct switch_val *val)
|
||||
{
|
||||
struct nlattr *p;
|
||||
int ports = val->attr->dev->ports;
|
||||
int err = 0;
|
||||
int remaining;
|
||||
|
||||
if (!val->value.ports)
|
||||
val->value.ports = malloc(sizeof(struct switch_port) * ports);
|
||||
|
||||
nla_for_each_nested(p, nla, remaining) {
|
||||
struct nlattr *tb[SWITCH_PORT_ATTR_MAX+1];
|
||||
struct switch_port *port;
|
||||
|
||||
if (val->len >= ports)
|
||||
break;
|
||||
|
||||
err = nla_parse_nested(tb, SWITCH_PORT_ATTR_MAX, p, port_policy);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
if (!tb[SWITCH_PORT_ID])
|
||||
continue;
|
||||
|
||||
port = &val->value.ports[val->len];
|
||||
port->id = nla_get_u32(tb[SWITCH_PORT_ID]);
|
||||
port->flags = 0;
|
||||
if (tb[SWITCH_PORT_FLAG_TAGGED])
|
||||
port->flags |= SWLIB_PORT_FLAG_TAGGED;
|
||||
|
||||
val->len++;
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
store_link_val(struct nl_msg *msg, struct nlattr *nla, struct switch_val *val)
|
||||
{
|
||||
struct nlattr *tb[SWITCH_LINK_ATTR_MAX + 1];
|
||||
struct switch_port_link *link;
|
||||
int err = 0;
|
||||
|
||||
if (!val->value.link)
|
||||
val->value.link = malloc(sizeof(struct switch_port_link));
|
||||
|
||||
err = nla_parse_nested(tb, SWITCH_LINK_ATTR_MAX, nla, link_policy);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
link = val->value.link;
|
||||
link->link = !!tb[SWITCH_LINK_FLAG_LINK];
|
||||
link->duplex = !!tb[SWITCH_LINK_FLAG_DUPLEX];
|
||||
link->aneg = !!tb[SWITCH_LINK_FLAG_ANEG];
|
||||
link->tx_flow = !!tb[SWITCH_LINK_FLAG_TX_FLOW];
|
||||
link->rx_flow = !!tb[SWITCH_LINK_FLAG_RX_FLOW];
|
||||
link->speed = nla_get_u32(tb[SWITCH_LINK_SPEED]);
|
||||
link->eee = 0;
|
||||
if (tb[SWITCH_LINK_FLAG_EEE_100BASET])
|
||||
link->eee |= SWLIB_LINK_FLAG_EEE_100BASET;
|
||||
if (tb[SWITCH_LINK_FLAG_EEE_1000BASET])
|
||||
link->eee |= SWLIB_LINK_FLAG_EEE_1000BASET;
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
store_val(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct switch_val *val = arg;
|
||||
|
||||
if (!val)
|
||||
goto error;
|
||||
|
||||
if (nla_parse(tb, SWITCH_ATTR_MAX - 1, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), NULL) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tb[SWITCH_ATTR_OP_VALUE_INT])
|
||||
val->value.i = nla_get_u32(tb[SWITCH_ATTR_OP_VALUE_INT]);
|
||||
else if (tb[SWITCH_ATTR_OP_VALUE_STR])
|
||||
val->value.s = strdup(nla_get_string(tb[SWITCH_ATTR_OP_VALUE_STR]));
|
||||
else if (tb[SWITCH_ATTR_OP_VALUE_PORTS])
|
||||
val->err = store_port_val(msg, tb[SWITCH_ATTR_OP_VALUE_PORTS], val);
|
||||
else if (tb[SWITCH_ATTR_OP_VALUE_LINK])
|
||||
val->err = store_link_val(msg, tb[SWITCH_ATTR_OP_VALUE_LINK], val);
|
||||
|
||||
val->err = 0;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int
|
||||
swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val)
|
||||
{
|
||||
int cmd;
|
||||
int err;
|
||||
|
||||
switch(attr->atype) {
|
||||
case SWLIB_ATTR_GROUP_GLOBAL:
|
||||
cmd = SWITCH_CMD_GET_GLOBAL;
|
||||
break;
|
||||
case SWLIB_ATTR_GROUP_PORT:
|
||||
cmd = SWITCH_CMD_GET_PORT;
|
||||
break;
|
||||
case SWLIB_ATTR_GROUP_VLAN:
|
||||
cmd = SWITCH_CMD_GET_VLAN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(&val->value, 0, sizeof(val->value));
|
||||
val->len = 0;
|
||||
val->attr = attr;
|
||||
val->err = -EINVAL;
|
||||
err = swlib_call(cmd, store_val, send_attr, val);
|
||||
if (!err)
|
||||
err = val->err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
send_attr_ports(struct nl_msg *msg, struct switch_val *val)
|
||||
{
|
||||
struct nlattr *n;
|
||||
int i;
|
||||
|
||||
/* TODO implement multipart? */
|
||||
if (val->len == 0)
|
||||
goto done;
|
||||
n = nla_nest_start(msg, SWITCH_ATTR_OP_VALUE_PORTS);
|
||||
if (!n)
|
||||
goto nla_put_failure;
|
||||
for (i = 0; i < val->len; i++) {
|
||||
struct switch_port *port = &val->value.ports[i];
|
||||
struct nlattr *np;
|
||||
|
||||
np = nla_nest_start(msg, SWITCH_ATTR_PORT);
|
||||
if (!np)
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U32(msg, SWITCH_PORT_ID, port->id);
|
||||
if (port->flags & SWLIB_PORT_FLAG_TAGGED)
|
||||
NLA_PUT_FLAG(msg, SWITCH_PORT_FLAG_TAGGED);
|
||||
|
||||
nla_nest_end(msg, np);
|
||||
}
|
||||
nla_nest_end(msg, n);
|
||||
done:
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
send_attr_link(struct nl_msg *msg, struct switch_val *val)
|
||||
{
|
||||
struct switch_port_link *link = val->value.link;
|
||||
struct nlattr *n;
|
||||
|
||||
n = nla_nest_start(msg, SWITCH_ATTR_OP_VALUE_LINK);
|
||||
if (!n)
|
||||
goto nla_put_failure;
|
||||
|
||||
if (link->duplex)
|
||||
NLA_PUT_FLAG(msg, SWITCH_LINK_FLAG_DUPLEX);
|
||||
if (link->aneg)
|
||||
NLA_PUT_FLAG(msg, SWITCH_LINK_FLAG_ANEG);
|
||||
NLA_PUT_U32(msg, SWITCH_LINK_SPEED, link->speed);
|
||||
|
||||
nla_nest_end(msg, n);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
send_attr_val(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct switch_val *val = arg;
|
||||
struct switch_attr *attr = val->attr;
|
||||
|
||||
if (send_attr(msg, arg))
|
||||
goto nla_put_failure;
|
||||
|
||||
switch(attr->type) {
|
||||
case SWITCH_TYPE_NOVAL:
|
||||
break;
|
||||
case SWITCH_TYPE_INT:
|
||||
NLA_PUT_U32(msg, SWITCH_ATTR_OP_VALUE_INT, val->value.i);
|
||||
break;
|
||||
case SWITCH_TYPE_STRING:
|
||||
if (!val->value.s)
|
||||
goto nla_put_failure;
|
||||
NLA_PUT_STRING(msg, SWITCH_ATTR_OP_VALUE_STR, val->value.s);
|
||||
break;
|
||||
case SWITCH_TYPE_PORTS:
|
||||
if (send_attr_ports(msg, val) < 0)
|
||||
goto nla_put_failure;
|
||||
break;
|
||||
case SWITCH_TYPE_LINK:
|
||||
if (send_attr_link(msg, val))
|
||||
goto nla_put_failure;
|
||||
break;
|
||||
default:
|
||||
goto nla_put_failure;
|
||||
}
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr, struct switch_val *val)
|
||||
{
|
||||
int cmd;
|
||||
|
||||
switch(attr->atype) {
|
||||
case SWLIB_ATTR_GROUP_GLOBAL:
|
||||
cmd = SWITCH_CMD_SET_GLOBAL;
|
||||
break;
|
||||
case SWLIB_ATTR_GROUP_PORT:
|
||||
cmd = SWITCH_CMD_SET_PORT;
|
||||
break;
|
||||
case SWLIB_ATTR_GROUP_VLAN:
|
||||
cmd = SWITCH_CMD_SET_VLAN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
val->attr = attr;
|
||||
return swlib_call(cmd, NULL, send_attr_val, val);
|
||||
}
|
||||
|
||||
enum {
|
||||
CMD_NONE,
|
||||
CMD_DUPLEX,
|
||||
CMD_ANEG,
|
||||
CMD_SPEED,
|
||||
};
|
||||
|
||||
int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *a, int port_vlan, const char *str)
|
||||
{
|
||||
struct switch_port *ports;
|
||||
struct switch_port_link *link;
|
||||
struct switch_val val;
|
||||
char *ptr;
|
||||
int cmd = CMD_NONE;
|
||||
|
||||
memset(&val, 0, sizeof(val));
|
||||
val.port_vlan = port_vlan;
|
||||
switch(a->type) {
|
||||
case SWITCH_TYPE_INT:
|
||||
val.value.i = atoi(str);
|
||||
break;
|
||||
case SWITCH_TYPE_STRING:
|
||||
val.value.s = (char *)str;
|
||||
break;
|
||||
case SWITCH_TYPE_PORTS:
|
||||
ports = alloca(sizeof(struct switch_port) * dev->ports);
|
||||
memset(ports, 0, sizeof(struct switch_port) * dev->ports);
|
||||
val.len = 0;
|
||||
ptr = (char *)str;
|
||||
while(ptr && *ptr)
|
||||
{
|
||||
while(*ptr && isspace(*ptr))
|
||||
ptr++;
|
||||
|
||||
if (!*ptr)
|
||||
break;
|
||||
|
||||
if (!isdigit(*ptr))
|
||||
return -1;
|
||||
|
||||
if (val.len >= dev->ports)
|
||||
return -1;
|
||||
|
||||
ports[val.len].flags = 0;
|
||||
ports[val.len].id = strtoul(ptr, &ptr, 10);
|
||||
while(*ptr && !isspace(*ptr)) {
|
||||
if (*ptr == 't')
|
||||
ports[val.len].flags |= SWLIB_PORT_FLAG_TAGGED;
|
||||
else
|
||||
return -1;
|
||||
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr)
|
||||
ptr++;
|
||||
val.len++;
|
||||
}
|
||||
val.value.ports = ports;
|
||||
break;
|
||||
case SWITCH_TYPE_LINK:
|
||||
link = malloc(sizeof(struct switch_port_link));
|
||||
memset(link, 0, sizeof(struct switch_port_link));
|
||||
ptr = (char *)str;
|
||||
for (ptr = strtok(ptr," "); ptr; ptr = strtok(NULL, " ")) {
|
||||
switch (cmd) {
|
||||
case CMD_NONE:
|
||||
if (!strcmp(ptr, "duplex"))
|
||||
cmd = CMD_DUPLEX;
|
||||
else if (!strcmp(ptr, "autoneg"))
|
||||
cmd = CMD_ANEG;
|
||||
else if (!strcmp(ptr, "speed"))
|
||||
cmd = CMD_SPEED;
|
||||
else
|
||||
fprintf(stderr, "Unsupported option %s\n", ptr);
|
||||
break;
|
||||
case CMD_DUPLEX:
|
||||
if (!strcmp(ptr, "half"))
|
||||
link->duplex = 0;
|
||||
else if (!strcmp(ptr, "full"))
|
||||
link->duplex = 1;
|
||||
else
|
||||
fprintf(stderr, "Unsupported value %s\n", ptr);
|
||||
cmd = CMD_NONE;
|
||||
break;
|
||||
case CMD_ANEG:
|
||||
if (!strcmp(ptr, "on"))
|
||||
link->aneg = 1;
|
||||
else if (!strcmp(ptr, "off"))
|
||||
link->aneg = 0;
|
||||
else
|
||||
fprintf(stderr, "Unsupported value %s\n", ptr);
|
||||
cmd = CMD_NONE;
|
||||
break;
|
||||
case CMD_SPEED:
|
||||
link->speed = atoi(ptr);
|
||||
cmd = CMD_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
val.value.link = link;
|
||||
break;
|
||||
case SWITCH_TYPE_NOVAL:
|
||||
if (str && !strcmp(str, "0"))
|
||||
return 0;
|
||||
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return swlib_set_attr(dev, a, &val);
|
||||
}
|
||||
|
||||
|
||||
struct attrlist_arg {
|
||||
int id;
|
||||
int atype;
|
||||
struct switch_dev *dev;
|
||||
struct switch_attr *prev;
|
||||
struct switch_attr **head;
|
||||
};
|
||||
|
||||
static int
|
||||
add_id(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct attrlist_arg *l = arg;
|
||||
|
||||
NLA_PUT_U32(msg, SWITCH_ATTR_ID, l->id);
|
||||
|
||||
return 0;
|
||||
nla_put_failure:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
add_attr(struct nl_msg *msg, void *ptr)
|
||||
{
|
||||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct attrlist_arg *arg = ptr;
|
||||
struct switch_attr *new;
|
||||
|
||||
if (nla_parse(tb, SWITCH_ATTR_MAX - 1, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), NULL) < 0)
|
||||
goto done;
|
||||
|
||||
new = swlib_alloc(sizeof(struct switch_attr));
|
||||
if (!new)
|
||||
goto done;
|
||||
|
||||
new->dev = arg->dev;
|
||||
new->atype = arg->atype;
|
||||
if (arg->prev) {
|
||||
arg->prev->next = new;
|
||||
} else {
|
||||
arg->prev = *arg->head;
|
||||
}
|
||||
*arg->head = new;
|
||||
arg->head = &new->next;
|
||||
|
||||
if (tb[SWITCH_ATTR_OP_ID])
|
||||
new->id = nla_get_u32(tb[SWITCH_ATTR_OP_ID]);
|
||||
if (tb[SWITCH_ATTR_OP_TYPE])
|
||||
new->type = nla_get_u32(tb[SWITCH_ATTR_OP_TYPE]);
|
||||
if (tb[SWITCH_ATTR_OP_NAME])
|
||||
new->name = strdup(nla_get_string(tb[SWITCH_ATTR_OP_NAME]));
|
||||
if (tb[SWITCH_ATTR_OP_DESCRIPTION])
|
||||
new->description = strdup(nla_get_string(tb[SWITCH_ATTR_OP_DESCRIPTION]));
|
||||
|
||||
done:
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int
|
||||
swlib_scan(struct switch_dev *dev)
|
||||
{
|
||||
struct attrlist_arg arg;
|
||||
|
||||
if (dev->ops || dev->port_ops || dev->vlan_ops)
|
||||
return 0;
|
||||
|
||||
arg.atype = SWLIB_ATTR_GROUP_GLOBAL;
|
||||
arg.dev = dev;
|
||||
arg.id = dev->id;
|
||||
arg.prev = NULL;
|
||||
arg.head = &dev->ops;
|
||||
swlib_call(SWITCH_CMD_LIST_GLOBAL, add_attr, add_id, &arg);
|
||||
|
||||
arg.atype = SWLIB_ATTR_GROUP_PORT;
|
||||
arg.prev = NULL;
|
||||
arg.head = &dev->port_ops;
|
||||
swlib_call(SWITCH_CMD_LIST_PORT, add_attr, add_id, &arg);
|
||||
|
||||
arg.atype = SWLIB_ATTR_GROUP_VLAN;
|
||||
arg.prev = NULL;
|
||||
arg.head = &dev->vlan_ops;
|
||||
swlib_call(SWITCH_CMD_LIST_VLAN, add_attr, add_id, &arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct switch_attr *swlib_lookup_attr(struct switch_dev *dev,
|
||||
enum swlib_attr_group atype, const char *name)
|
||||
{
|
||||
struct switch_attr *head;
|
||||
|
||||
if (!name || !dev)
|
||||
return NULL;
|
||||
|
||||
switch(atype) {
|
||||
case SWLIB_ATTR_GROUP_GLOBAL:
|
||||
head = dev->ops;
|
||||
break;
|
||||
case SWLIB_ATTR_GROUP_PORT:
|
||||
head = dev->port_ops;
|
||||
break;
|
||||
case SWLIB_ATTR_GROUP_VLAN:
|
||||
head = dev->vlan_ops;
|
||||
break;
|
||||
}
|
||||
while(head) {
|
||||
if (!strcmp(name, head->name))
|
||||
return head;
|
||||
head = head->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
swlib_priv_free(void)
|
||||
{
|
||||
if (family)
|
||||
nl_object_put((struct nl_object*)family);
|
||||
if (cache)
|
||||
nl_cache_free(cache);
|
||||
if (handle)
|
||||
nl_socket_free(handle);
|
||||
family = NULL;
|
||||
handle = NULL;
|
||||
cache = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
swlib_priv_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
handle = nl_socket_alloc();
|
||||
if (!handle) {
|
||||
DPRINTF("Failed to create handle\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (genl_connect(handle)) {
|
||||
DPRINTF("Failed to connect to generic netlink\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = genl_ctrl_alloc_cache(handle, &cache);
|
||||
if (ret < 0) {
|
||||
DPRINTF("Failed to allocate netlink cache\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
family = genl_ctrl_search_by_name(cache, "switch");
|
||||
if (!family) {
|
||||
DPRINTF("Switch API not present\n");
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
swlib_priv_free();
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
struct swlib_scan_arg {
|
||||
const char *name;
|
||||
struct switch_dev *head;
|
||||
struct switch_dev *ptr;
|
||||
};
|
||||
|
||||
static int
|
||||
add_port_map(struct switch_dev *dev, struct nlattr *nla)
|
||||
{
|
||||
struct nlattr *p;
|
||||
int err = 0, idx = 0;
|
||||
int remaining;
|
||||
|
||||
dev->maps = malloc(sizeof(struct switch_portmap) * dev->ports);
|
||||
if (!dev->maps)
|
||||
return -1;
|
||||
memset(dev->maps, 0, sizeof(struct switch_portmap) * dev->ports);
|
||||
|
||||
nla_for_each_nested(p, nla, remaining) {
|
||||
struct nlattr *tb[SWITCH_PORTMAP_MAX+1];
|
||||
|
||||
if (idx >= dev->ports)
|
||||
continue;
|
||||
|
||||
err = nla_parse_nested(tb, SWITCH_PORTMAP_MAX, p, portmap_policy);
|
||||
if (err < 0)
|
||||
continue;
|
||||
|
||||
|
||||
if (tb[SWITCH_PORTMAP_SEGMENT] && tb[SWITCH_PORTMAP_VIRT]) {
|
||||
dev->maps[idx].segment = strdup(nla_get_string(tb[SWITCH_PORTMAP_SEGMENT]));
|
||||
dev->maps[idx].virt = nla_get_u32(tb[SWITCH_PORTMAP_VIRT]);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
add_switch(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct swlib_scan_arg *sa = arg;
|
||||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct switch_dev *dev;
|
||||
const char *name;
|
||||
const char *alias;
|
||||
|
||||
if (nla_parse(tb, SWITCH_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0)
|
||||
goto done;
|
||||
|
||||
if (!tb[SWITCH_ATTR_DEV_NAME])
|
||||
goto done;
|
||||
|
||||
name = nla_get_string(tb[SWITCH_ATTR_DEV_NAME]);
|
||||
alias = nla_get_string(tb[SWITCH_ATTR_ALIAS]);
|
||||
|
||||
if (sa->name && (strcmp(name, sa->name) != 0) && (strcmp(alias, sa->name) != 0))
|
||||
goto done;
|
||||
|
||||
dev = swlib_alloc(sizeof(struct switch_dev));
|
||||
if (!dev)
|
||||
goto done;
|
||||
|
||||
strncpy(dev->dev_name, name, IFNAMSIZ - 1);
|
||||
dev->alias = strdup(alias);
|
||||
if (tb[SWITCH_ATTR_ID])
|
||||
dev->id = nla_get_u32(tb[SWITCH_ATTR_ID]);
|
||||
if (tb[SWITCH_ATTR_NAME])
|
||||
dev->name = strdup(nla_get_string(tb[SWITCH_ATTR_NAME]));
|
||||
if (tb[SWITCH_ATTR_PORTS])
|
||||
dev->ports = nla_get_u32(tb[SWITCH_ATTR_PORTS]);
|
||||
if (tb[SWITCH_ATTR_VLANS])
|
||||
dev->vlans = nla_get_u32(tb[SWITCH_ATTR_VLANS]);
|
||||
if (tb[SWITCH_ATTR_CPU_PORT])
|
||||
dev->cpu_port = nla_get_u32(tb[SWITCH_ATTR_CPU_PORT]);
|
||||
if (tb[SWITCH_ATTR_PORTMAP])
|
||||
add_port_map(dev, tb[SWITCH_ATTR_PORTMAP]);
|
||||
|
||||
if (!sa->head) {
|
||||
sa->head = dev;
|
||||
sa->ptr = dev;
|
||||
} else {
|
||||
sa->ptr->next = dev;
|
||||
sa->ptr = dev;
|
||||
}
|
||||
|
||||
refcount++;
|
||||
done:
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
static int
|
||||
list_switch(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
|
||||
if (nla_parse(tb, SWITCH_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL) < 0)
|
||||
goto done;
|
||||
|
||||
if (!tb[SWITCH_ATTR_DEV_NAME] || !tb[SWITCH_ATTR_NAME])
|
||||
goto done;
|
||||
|
||||
printf("Found: %s - %s\n", nla_get_string(tb[SWITCH_ATTR_DEV_NAME]),
|
||||
nla_get_string(tb[SWITCH_ATTR_ALIAS]));
|
||||
|
||||
done:
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
void
|
||||
swlib_list(void)
|
||||
{
|
||||
if (swlib_priv_init() < 0)
|
||||
return;
|
||||
swlib_call(SWITCH_CMD_GET_SWITCH, list_switch, NULL, NULL);
|
||||
swlib_priv_free();
|
||||
}
|
||||
|
||||
void
|
||||
swlib_print_portmap(struct switch_dev *dev, char *segment)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (segment) {
|
||||
if (!strcmp(segment, "cpu")) {
|
||||
printf("%d ", dev->cpu_port);
|
||||
} else if (!strcmp(segment, "disabled")) {
|
||||
for (i = 0; i < dev->ports; i++)
|
||||
if (!dev->maps[i].segment)
|
||||
printf("%d ", i);
|
||||
} else for (i = 0; i < dev->ports; i++) {
|
||||
if (dev->maps[i].segment && !strcmp(dev->maps[i].segment, segment))
|
||||
printf("%d ", i);
|
||||
}
|
||||
} else {
|
||||
printf("%s - %s\n", dev->dev_name, dev->name);
|
||||
for (i = 0; i < dev->ports; i++)
|
||||
if (i == dev->cpu_port)
|
||||
printf("port%d:\tcpu\n", i);
|
||||
else if (dev->maps[i].segment)
|
||||
printf("port%d:\t%s.%d\n", i, dev->maps[i].segment, dev->maps[i].virt);
|
||||
else
|
||||
printf("port%d:\tdisabled\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
struct switch_dev *
|
||||
swlib_connect(const char *name)
|
||||
{
|
||||
struct swlib_scan_arg arg;
|
||||
|
||||
if (!refcount) {
|
||||
if (swlib_priv_init() < 0)
|
||||
return NULL;
|
||||
};
|
||||
|
||||
arg.head = NULL;
|
||||
arg.ptr = NULL;
|
||||
arg.name = name;
|
||||
swlib_call(SWITCH_CMD_GET_SWITCH, add_switch, NULL, &arg);
|
||||
|
||||
if (!refcount)
|
||||
swlib_priv_free();
|
||||
|
||||
return arg.head;
|
||||
}
|
||||
|
||||
static void
|
||||
swlib_free_attributes(struct switch_attr **head)
|
||||
{
|
||||
struct switch_attr *a = *head;
|
||||
struct switch_attr *next;
|
||||
|
||||
while (a) {
|
||||
next = a->next;
|
||||
free(a->name);
|
||||
free(a->description);
|
||||
free(a);
|
||||
a = next;
|
||||
}
|
||||
*head = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
swlib_free_port_map(struct switch_dev *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!dev || !dev->maps)
|
||||
return;
|
||||
|
||||
for (i = 0; i < dev->ports; i++)
|
||||
free(dev->maps[i].segment);
|
||||
free(dev->maps);
|
||||
}
|
||||
|
||||
void
|
||||
swlib_free(struct switch_dev *dev)
|
||||
{
|
||||
swlib_free_attributes(&dev->ops);
|
||||
swlib_free_attributes(&dev->port_ops);
|
||||
swlib_free_attributes(&dev->vlan_ops);
|
||||
swlib_free_port_map(dev);
|
||||
free(dev->name);
|
||||
free(dev->alias);
|
||||
free(dev);
|
||||
|
||||
if (--refcount == 0)
|
||||
swlib_priv_free();
|
||||
}
|
||||
|
||||
void
|
||||
swlib_free_all(struct switch_dev *dev)
|
||||
{
|
||||
struct switch_dev *p;
|
||||
|
||||
while (dev) {
|
||||
p = dev->next;
|
||||
swlib_free(dev);
|
||||
dev = p;
|
||||
}
|
||||
}
|
||||
269
package/network/config/swconfig/src/swlib.h
Normal file
269
package/network/config/swconfig/src/swlib.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* swlib.h: Switch configuration API (user space part)
|
||||
*
|
||||
* Copyright (C) 2008-2009 Felix Fietkau <nbd@nbd.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* version 2.1 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
|
||||
Usage of the library functions:
|
||||
|
||||
The main datastructure for a switch is the struct switch_device
|
||||
To get started, you first need to use switch_connect() to probe
|
||||
for switches and allocate an instance of this struct.
|
||||
|
||||
There are two possible usage modes:
|
||||
dev = switch_connect("eth0");
|
||||
- this call will look for a switch registered for the linux device
|
||||
"eth0" and only allocate a switch_device for this particular switch.
|
||||
|
||||
dev = switch_connect(NULL)
|
||||
- this will return one switch_device struct for each available
|
||||
switch. The switch_device structs are chained with by ->next pointer
|
||||
|
||||
Then to query a switch for all available attributes, use:
|
||||
swlib_scan(dev);
|
||||
|
||||
All allocated datastructures for the switch_device struct can be freed with
|
||||
swlib_free(dev);
|
||||
or
|
||||
swlib_free_all(dev);
|
||||
|
||||
The latter traverses a whole chain of switch_device structs and frees them all
|
||||
|
||||
Switch attributes (struct switch_attr) are divided into three groups:
|
||||
dev->ops:
|
||||
- global settings
|
||||
dev->port_ops:
|
||||
- per-port settings
|
||||
dev->vlan_ops:
|
||||
- per-vlan settings
|
||||
|
||||
switch_lookup_attr() is a small helper function to locate attributes
|
||||
by name.
|
||||
|
||||
switch_set_attr() and switch_get_attr() can alter or request the values
|
||||
of attributes.
|
||||
|
||||
Usage of the switch_attr struct:
|
||||
|
||||
->atype: attribute group, one of:
|
||||
- SWLIB_ATTR_GROUP_GLOBAL
|
||||
- SWLIB_ATTR_GROUP_VLAN
|
||||
- SWLIB_ATTR_GROUP_PORT
|
||||
|
||||
->id: identifier for the attribute
|
||||
|
||||
->type: data type, one of:
|
||||
- SWITCH_TYPE_INT
|
||||
- SWITCH_TYPE_STRING
|
||||
- SWITCH_TYPE_PORT
|
||||
|
||||
->name: short name of the attribute
|
||||
->description: longer description
|
||||
->next: pointer to the next attribute of the current group
|
||||
|
||||
|
||||
Usage of the switch_val struct:
|
||||
|
||||
When setting attributes, following members of the struct switch_val need
|
||||
to be set up:
|
||||
|
||||
->len (for attr->type == SWITCH_TYPE_PORT)
|
||||
->port_vlan:
|
||||
- port number (for attr->atype == SWLIB_ATTR_GROUP_PORT), or:
|
||||
- vlan number (for attr->atype == SWLIB_ATTR_GROUP_VLAN)
|
||||
->value.i (for attr->type == SWITCH_TYPE_INT)
|
||||
->value.s (for attr->type == SWITCH_TYPE_STRING)
|
||||
- owned by the caller, not stored in the library internally
|
||||
->value.ports (for attr->type == SWITCH_TYPE_PORT)
|
||||
- must point to an array of at lest val->len * sizeof(struct switch_port)
|
||||
|
||||
When getting string attributes, val->value.s must be freed by the caller
|
||||
When getting port list attributes, an internal static buffer is used,
|
||||
which changes from call to call.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __SWLIB_H
|
||||
#define __SWLIB_H
|
||||
|
||||
enum swlib_attr_group {
|
||||
SWLIB_ATTR_GROUP_GLOBAL,
|
||||
SWLIB_ATTR_GROUP_VLAN,
|
||||
SWLIB_ATTR_GROUP_PORT,
|
||||
};
|
||||
|
||||
enum swlib_port_flags {
|
||||
SWLIB_PORT_FLAG_TAGGED = (1 << 0),
|
||||
};
|
||||
|
||||
enum swlib_link_flags {
|
||||
SWLIB_LINK_FLAG_EEE_100BASET = (1 << 0),
|
||||
SWLIB_LINK_FLAG_EEE_1000BASET = (1 << 1),
|
||||
};
|
||||
|
||||
struct switch_dev;
|
||||
struct switch_attr;
|
||||
struct switch_port;
|
||||
struct switch_port_map;
|
||||
struct switch_port_link;
|
||||
struct switch_val;
|
||||
struct uci_package;
|
||||
|
||||
struct switch_dev {
|
||||
int id;
|
||||
char dev_name[IFNAMSIZ];
|
||||
char *name;
|
||||
char *alias;
|
||||
int ports;
|
||||
int vlans;
|
||||
int cpu_port;
|
||||
struct switch_attr *ops;
|
||||
struct switch_attr *port_ops;
|
||||
struct switch_attr *vlan_ops;
|
||||
struct switch_portmap *maps;
|
||||
struct switch_dev *next;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
struct switch_val {
|
||||
struct switch_attr *attr;
|
||||
int len;
|
||||
int err;
|
||||
int port_vlan;
|
||||
union {
|
||||
char *s;
|
||||
int i;
|
||||
struct switch_port *ports;
|
||||
struct switch_port_link *link;
|
||||
} value;
|
||||
};
|
||||
|
||||
struct switch_attr {
|
||||
struct switch_dev *dev;
|
||||
int atype;
|
||||
int id;
|
||||
int type;
|
||||
char *name;
|
||||
char *description;
|
||||
struct switch_attr *next;
|
||||
};
|
||||
|
||||
struct switch_port {
|
||||
unsigned int id;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct switch_portmap {
|
||||
unsigned int virt;
|
||||
char *segment;
|
||||
};
|
||||
|
||||
struct switch_port_link {
|
||||
int link:1;
|
||||
int duplex:1;
|
||||
int aneg:1;
|
||||
int tx_flow:1;
|
||||
int rx_flow:1;
|
||||
int speed;
|
||||
/* in ethtool adv_t format */
|
||||
uint32_t eee;
|
||||
};
|
||||
|
||||
/**
|
||||
* swlib_list: list all switches
|
||||
*/
|
||||
void swlib_list(void);
|
||||
|
||||
/**
|
||||
* swlib_print_portmap: get portmap
|
||||
* @dev: switch device struct
|
||||
*/
|
||||
void swlib_print_portmap(struct switch_dev *dev, char *segment);
|
||||
|
||||
/**
|
||||
* swlib_connect: connect to the switch through netlink
|
||||
* @name: name of the ethernet interface,
|
||||
*
|
||||
* if name is NULL, it connect and builds a chain of all switches
|
||||
*/
|
||||
struct switch_dev *swlib_connect(const char *name);
|
||||
|
||||
/**
|
||||
* swlib_free: free all dynamically allocated data for the switch connection
|
||||
* @dev: switch device struct
|
||||
*
|
||||
* all members of a switch device chain (generated by swlib_connect(NULL))
|
||||
* must be freed individually
|
||||
*/
|
||||
void swlib_free(struct switch_dev *dev);
|
||||
|
||||
/**
|
||||
* swlib_free_all: run swlib_free on all devices in the chain
|
||||
* @dev: switch device struct
|
||||
*/
|
||||
void swlib_free_all(struct switch_dev *dev);
|
||||
|
||||
/**
|
||||
* swlib_scan: probe the switch driver for available commands/attributes
|
||||
* @dev: switch device struct
|
||||
*/
|
||||
int swlib_scan(struct switch_dev *dev);
|
||||
|
||||
/**
|
||||
* swlib_lookup_attr: look up a switch attribute
|
||||
* @dev: switch device struct
|
||||
* @type: global, port or vlan
|
||||
* @name: name of the attribute
|
||||
*/
|
||||
struct switch_attr *swlib_lookup_attr(struct switch_dev *dev,
|
||||
enum swlib_attr_group atype, const char *name);
|
||||
|
||||
/**
|
||||
* swlib_set_attr: set the value for an attribute
|
||||
* @dev: switch device struct
|
||||
* @attr: switch attribute struct
|
||||
* @val: attribute value pointer
|
||||
* returns 0 on success
|
||||
*/
|
||||
int swlib_set_attr(struct switch_dev *dev, struct switch_attr *attr,
|
||||
struct switch_val *val);
|
||||
|
||||
/**
|
||||
* swlib_set_attr_string: set the value for an attribute with type conversion
|
||||
* @dev: switch device struct
|
||||
* @attr: switch attribute struct
|
||||
* @port_vlan: port or vlan (if applicable)
|
||||
* @str: string value
|
||||
* returns 0 on success
|
||||
*/
|
||||
int swlib_set_attr_string(struct switch_dev *dev, struct switch_attr *attr,
|
||||
int port_vlan, const char *str);
|
||||
|
||||
/**
|
||||
* swlib_get_attr: get the value for an attribute
|
||||
* @dev: switch device struct
|
||||
* @attr: switch attribute struct
|
||||
* @val: attribute value pointer
|
||||
* returns 0 on success
|
||||
* for string attributes, the result string must be freed by the caller
|
||||
*/
|
||||
int swlib_get_attr(struct switch_dev *dev, struct switch_attr *attr,
|
||||
struct switch_val *val);
|
||||
|
||||
/**
|
||||
* swlib_apply_from_uci: set up the switch from a uci configuration
|
||||
* @dev: switch device struct
|
||||
* @p: uci package which contains the desired global config
|
||||
*/
|
||||
int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p);
|
||||
|
||||
#endif
|
||||
246
package/network/config/swconfig/src/uci.c
Normal file
246
package/network/config/swconfig/src/uci.c
Normal file
@@ -0,0 +1,246 @@
|
||||
/*
|
||||
* uci.c: UCI binding for the switch configuration utility
|
||||
*
|
||||
* Copyright (C) 2009 Felix Fietkau <nbd@nbd.name>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundatio.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <uci.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/switch.h>
|
||||
#include "swlib.h"
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
struct swlib_setting {
|
||||
struct switch_attr *attr;
|
||||
const char *name;
|
||||
int port_vlan;
|
||||
const char *val;
|
||||
struct swlib_setting *next;
|
||||
};
|
||||
|
||||
struct swlib_setting early_settings[] = {
|
||||
{ .name = "reset", .val = "1" },
|
||||
{ .name = "enable_vlan", .val = "1" },
|
||||
};
|
||||
|
||||
static struct swlib_setting *settings;
|
||||
static struct swlib_setting **head;
|
||||
|
||||
static bool swlib_match_name(struct switch_dev *dev, const char *name)
|
||||
{
|
||||
return (strcmp(name, dev->dev_name) == 0 ||
|
||||
strcmp(name, dev->alias) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
swlib_map_settings(struct switch_dev *dev, int type, int port_vlan, struct uci_section *s)
|
||||
{
|
||||
struct swlib_setting *setting;
|
||||
struct switch_attr *attr;
|
||||
struct uci_element *e;
|
||||
struct uci_option *o;
|
||||
|
||||
uci_foreach_element(&s->options, e) {
|
||||
o = uci_to_option(e);
|
||||
|
||||
if (o->type != UCI_TYPE_STRING)
|
||||
continue;
|
||||
|
||||
if (!strcmp(e->name, "device"))
|
||||
continue;
|
||||
|
||||
/* map early settings */
|
||||
if (type == SWLIB_ATTR_GROUP_GLOBAL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
|
||||
if (strcmp(e->name, early_settings[i].name) != 0)
|
||||
continue;
|
||||
|
||||
early_settings[i].val = o->v.string;
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
attr = swlib_lookup_attr(dev, type, e->name);
|
||||
if (!attr)
|
||||
continue;
|
||||
|
||||
setting = malloc(sizeof(struct swlib_setting));
|
||||
memset(setting, 0, sizeof(struct swlib_setting));
|
||||
setting->attr = attr;
|
||||
setting->port_vlan = port_vlan;
|
||||
setting->val = o->v.string;
|
||||
*head = setting;
|
||||
head = &setting->next;
|
||||
skip:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int swlib_apply_from_uci(struct switch_dev *dev, struct uci_package *p)
|
||||
{
|
||||
struct switch_attr *attr;
|
||||
struct uci_element *e;
|
||||
struct uci_section *s;
|
||||
struct uci_option *o;
|
||||
struct uci_ptr ptr;
|
||||
struct switch_val val;
|
||||
int i;
|
||||
|
||||
settings = NULL;
|
||||
head = &settings;
|
||||
|
||||
uci_foreach_element(&p->sections, e) {
|
||||
struct uci_element *n;
|
||||
|
||||
s = uci_to_section(e);
|
||||
|
||||
if (strcmp(s->type, "switch") != 0)
|
||||
continue;
|
||||
|
||||
uci_foreach_element(&s->options, n) {
|
||||
struct uci_option *o = uci_to_option(n);
|
||||
|
||||
if (strcmp(n->name, "name") != 0)
|
||||
continue;
|
||||
|
||||
if (o->type != UCI_TYPE_STRING)
|
||||
continue;
|
||||
|
||||
if (swlib_match_name(dev, o->v.string))
|
||||
goto found;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!swlib_match_name(dev, e->name))
|
||||
continue;
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* not found */
|
||||
return -1;
|
||||
|
||||
found:
|
||||
/* look up available early options, which need to be taken care
|
||||
* of in the correct order */
|
||||
for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
|
||||
early_settings[i].attr = swlib_lookup_attr(dev,
|
||||
SWLIB_ATTR_GROUP_GLOBAL, early_settings[i].name);
|
||||
}
|
||||
swlib_map_settings(dev, SWLIB_ATTR_GROUP_GLOBAL, 0, s);
|
||||
|
||||
/* look for port or vlan sections */
|
||||
uci_foreach_element(&p->sections, e) {
|
||||
struct uci_element *os;
|
||||
s = uci_to_section(e);
|
||||
|
||||
if (!strcmp(s->type, "switch_port")) {
|
||||
char *devn = NULL, *port = NULL, *port_err = NULL;
|
||||
int port_n;
|
||||
|
||||
uci_foreach_element(&s->options, os) {
|
||||
o = uci_to_option(os);
|
||||
if (o->type != UCI_TYPE_STRING)
|
||||
continue;
|
||||
|
||||
if (!strcmp(os->name, "device")) {
|
||||
devn = o->v.string;
|
||||
if (!swlib_match_name(dev, devn))
|
||||
devn = NULL;
|
||||
} else if (!strcmp(os->name, "port")) {
|
||||
port = o->v.string;
|
||||
}
|
||||
}
|
||||
if (!devn || !port || !port[0])
|
||||
continue;
|
||||
|
||||
port_n = strtoul(port, &port_err, 0);
|
||||
if (port_err && port_err[0])
|
||||
continue;
|
||||
|
||||
swlib_map_settings(dev, SWLIB_ATTR_GROUP_PORT, port_n, s);
|
||||
} else if (!strcmp(s->type, "switch_vlan")) {
|
||||
char *devn = NULL, *vlan = NULL, *vlan_err = NULL;
|
||||
int vlan_n;
|
||||
|
||||
uci_foreach_element(&s->options, os) {
|
||||
o = uci_to_option(os);
|
||||
if (o->type != UCI_TYPE_STRING)
|
||||
continue;
|
||||
|
||||
if (!strcmp(os->name, "device")) {
|
||||
devn = o->v.string;
|
||||
if (!swlib_match_name(dev, devn))
|
||||
devn = NULL;
|
||||
} else if (!strcmp(os->name, "vlan")) {
|
||||
vlan = o->v.string;
|
||||
}
|
||||
}
|
||||
if (!devn || !vlan || !vlan[0])
|
||||
continue;
|
||||
|
||||
vlan_n = strtoul(vlan, &vlan_err, 0);
|
||||
if (vlan_err && vlan_err[0])
|
||||
continue;
|
||||
|
||||
swlib_map_settings(dev, SWLIB_ATTR_GROUP_VLAN, vlan_n, s);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(early_settings); i++) {
|
||||
struct swlib_setting *st = &early_settings[i];
|
||||
if (!st->attr || !st->val)
|
||||
continue;
|
||||
swlib_set_attr_string(dev, st->attr, st->port_vlan, st->val);
|
||||
|
||||
}
|
||||
|
||||
while (settings) {
|
||||
struct swlib_setting *st = settings;
|
||||
|
||||
swlib_set_attr_string(dev, st->attr, st->port_vlan, st->val);
|
||||
st = st->next;
|
||||
free(settings);
|
||||
settings = st;
|
||||
}
|
||||
|
||||
/* Apply the config */
|
||||
attr = swlib_lookup_attr(dev, SWLIB_ATTR_GROUP_GLOBAL, "apply");
|
||||
if (!attr)
|
||||
return 0;
|
||||
|
||||
memset(&val, 0, sizeof(val));
|
||||
swlib_set_attr(dev, attr, &val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
73
package/network/config/vti/Makefile
Normal file
73
package/network/config/vti/Makefile
Normal file
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# Copyright (C) 2014 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=vti
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=2
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/vti/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
MAINTAINER:=Andre Valentin <avalentin@marcant.net>
|
||||
endef
|
||||
|
||||
define Package/vti
|
||||
$(call Package/vti/Default)
|
||||
TITLE:=Virtual IPsec Tunnel Interface config support
|
||||
endef
|
||||
|
||||
define Package/vti/description
|
||||
Virtual IPsec Tunnel Interface config support (IPv4 and IPv6) in /etc/config/network.
|
||||
endef
|
||||
|
||||
define Package/vtiv4
|
||||
$(call Package/vti/Default)
|
||||
TITLE:=Virtual IPsec Tunnel Interface (IPv4) config support
|
||||
DEPENDS:=@(PACKAGE_vti) +kmod-ip-vti
|
||||
endef
|
||||
|
||||
define Package/vtiv4/description
|
||||
Virtual IPsec Tunnel Interface config support (IPv4) in /etc/config/network.
|
||||
endef
|
||||
|
||||
define Package/vtiv6
|
||||
$(call Package/vti/Default)
|
||||
TITLE:=Virtual IPsec Tunnel Interface (IPv6) config support
|
||||
DEPENDS:=@(PACKAGE_vti) @IPV6 +kmod-ip6-vti
|
||||
endef
|
||||
|
||||
define Package/vtiv6/description
|
||||
Virtual IPsec Tunnel Interface config support (IPv6) in /etc/config/network.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/vti/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/vti.sh $(1)/lib/netifd/proto/vti.sh
|
||||
endef
|
||||
|
||||
define Package/vtiv4/install
|
||||
:
|
||||
endef
|
||||
|
||||
define Package/vtiv6/install
|
||||
:
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,vti))
|
||||
$(eval $(call BuildPackage,vtiv4))
|
||||
$(eval $(call BuildPackage,vtiv6))
|
||||
156
package/network/config/vti/files/vti.sh
Executable file
156
package/network/config/vti/files/vti.sh
Executable file
@@ -0,0 +1,156 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
vti_generic_setup() {
|
||||
local cfg="$1"
|
||||
local mode="$2"
|
||||
local local="$3"
|
||||
local remote="$4"
|
||||
local link="$5"
|
||||
local mtu zone ikey
|
||||
json_get_vars mtu zone ikey okey
|
||||
|
||||
[ -z "$zone" ] && zone="wan"
|
||||
|
||||
proto_init_update "$link" 1
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode "$mode"
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
json_add_string local "$local"
|
||||
json_add_string remote "$remote"
|
||||
[ -n "$tunlink" ] && json_add_string link "$tunlink"
|
||||
|
||||
json_add_object 'data'
|
||||
[ -n "$ikey" ] && json_add_int ikey "$ikey"
|
||||
[ -n "$okey" ] && json_add_int okey "$okey"
|
||||
json_close_object
|
||||
|
||||
proto_close_tunnel
|
||||
|
||||
proto_add_data
|
||||
[ -n "$zone" ] && json_add_string zone "$zone"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$cfg"
|
||||
}
|
||||
|
||||
vti_setup() {
|
||||
local cfg="$1"
|
||||
local mode="$2"
|
||||
|
||||
local ipaddr peeraddr
|
||||
json_get_vars df ipaddr peeraddr tunlink
|
||||
|
||||
[ -z "$peeraddr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
exit
|
||||
}
|
||||
|
||||
( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
|
||||
|
||||
[ -z "$ipaddr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z $wanif ] && ! network_find_wan wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr ipaddr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
vti_generic_setup $cfg $mode $ipaddr $peeraddr "vti-$cfg"
|
||||
}
|
||||
|
||||
proto_vti_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
vti_setup $cfg "vtiip"
|
||||
}
|
||||
|
||||
vti6_setup() {
|
||||
local cfg="$1"
|
||||
local mode="$2"
|
||||
|
||||
local ip6addr peer6addr weakif
|
||||
json_get_vars ip6addr peer6addr tunlink weakif
|
||||
|
||||
[ -z "$peer6addr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
exit
|
||||
}
|
||||
|
||||
( proto_add_host_dependency "$cfg" "$peer6addr" "$tunlink" )
|
||||
|
||||
[ -z "$ip6addr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z $wanif ] && ! network_find_wan6 wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr6 ip6addr "$wanif"; then
|
||||
[ -z "$weakif" ] && weakif="lan"
|
||||
if ! network_get_ipaddr6 ip6addr "$weakif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
vti_generic_setup $cfg $mode $ip6addr $peer6addr "vti6-$cfg"
|
||||
}
|
||||
|
||||
proto_vti6_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
vti6_setup $cfg "vtiip6"
|
||||
}
|
||||
|
||||
proto_vti_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_vti6_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
vti_generic_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_string "zone"
|
||||
proto_config_add_int "ikey"
|
||||
proto_config_add_int "okey"
|
||||
}
|
||||
|
||||
proto_vti_init_config() {
|
||||
vti_generic_init_config
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_string "peeraddr"
|
||||
}
|
||||
|
||||
proto_vti6_init_config() {
|
||||
vti_generic_init_config
|
||||
proto_config_add_string "ip6addr"
|
||||
proto_config_add_string "peer6addr"
|
||||
proto_config_add_string "weakif"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
[ -f /lib/modules/$(uname -r)/ip_vti.ko ] && add_protocol vti
|
||||
[ -f /lib/modules/$(uname -r)/ip6_vti.ko ] && add_protocol vti6
|
||||
}
|
||||
32
package/network/config/vxlan/Makefile
Normal file
32
package/network/config/vxlan/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=vxlan
|
||||
PKG_VERSION:=2
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/vxlan
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
MAINTAINER:=Matthias Schiffer <mschiffer@universe-factory.net>
|
||||
TITLE:=Virtual eXtensible LAN config support
|
||||
DEPENDS:=+kmod-vxlan
|
||||
endef
|
||||
|
||||
define Package/vxlan/description
|
||||
Virtual eXtensible LAN config support in /etc/config/network.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/vxlan/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/vxlan.sh $(1)/lib/netifd/proto/vxlan.sh
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,vxlan))
|
||||
150
package/network/config/vxlan/files/vxlan.sh
Executable file
150
package/network/config/vxlan/files/vxlan.sh
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
vxlan_generic_setup() {
|
||||
local cfg="$1"
|
||||
local mode="$2"
|
||||
local local="$3"
|
||||
local remote="$4"
|
||||
|
||||
local link="$cfg"
|
||||
|
||||
local port vid ttl tos mtu macaddr zone rxcsum txcsum
|
||||
json_get_vars port vid ttl tos mtu macaddr zone rxcsum txcsum
|
||||
|
||||
|
||||
proto_init_update "$link" 1
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode "$mode"
|
||||
|
||||
[ -n "$tunlink" ] && json_add_string link "$tunlink"
|
||||
[ -n "$local" ] && json_add_string local "$local"
|
||||
[ -n "$remote" ] && json_add_string remote "$remote"
|
||||
|
||||
[ -n "$ttl" ] && json_add_int ttl "$ttl"
|
||||
[ -n "$tos" ] && json_add_string tos "$tos"
|
||||
[ -n "$mtu" ] && json_add_int mtu "$mtu"
|
||||
|
||||
json_add_object 'data'
|
||||
[ -n "$port" ] && json_add_int port "$port"
|
||||
[ -n "$vid" ] && json_add_int id "$vid"
|
||||
[ -n "$macaddr" ] && json_add_string macaddr "$macaddr"
|
||||
[ -n "$rxcsum" ] && json_add_boolean rxcsum "$rxcsum"
|
||||
[ -n "$txcsum" ] && json_add_boolean txcsum "$txcsum"
|
||||
json_close_object
|
||||
|
||||
proto_close_tunnel
|
||||
|
||||
proto_add_data
|
||||
[ -n "$zone" ] && json_add_string zone "$zone"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$cfg"
|
||||
}
|
||||
|
||||
proto_vxlan_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
local ipaddr peeraddr
|
||||
json_get_vars ipaddr peeraddr tunlink
|
||||
|
||||
[ -z "$peeraddr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
exit
|
||||
}
|
||||
|
||||
( proto_add_host_dependency "$cfg" '' "$tunlink" )
|
||||
|
||||
[ -z "$ipaddr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z "$wanif" ] && ! network_find_wan wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr ipaddr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
vxlan_generic_setup "$cfg" 'vxlan' "$ipaddr" "$peeraddr"
|
||||
}
|
||||
|
||||
proto_vxlan6_setup() {
|
||||
local cfg="$1"
|
||||
|
||||
local ip6addr peer6addr
|
||||
json_get_vars ip6addr peer6addr tunlink
|
||||
|
||||
[ -z "$peer6addr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
exit
|
||||
}
|
||||
|
||||
( proto_add_host_dependency "$cfg" '' "$tunlink" )
|
||||
|
||||
[ -z "$ip6addr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z "$wanif" ] && ! network_find_wan6 wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr6 ip6addr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
exit
|
||||
fi
|
||||
}
|
||||
|
||||
vxlan_generic_setup "$cfg" 'vxlan6' "$ip6addr" "$peer6addr"
|
||||
}
|
||||
|
||||
proto_vxlan_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_vxlan6_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
vxlan_generic_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_string "zone"
|
||||
|
||||
proto_config_add_int "vid"
|
||||
proto_config_add_int "port"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_int "tos"
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_string "macaddr"
|
||||
}
|
||||
|
||||
proto_vxlan_init_config() {
|
||||
vxlan_generic_init_config
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_string "peeraddr"
|
||||
}
|
||||
|
||||
proto_vxlan6_init_config() {
|
||||
vxlan_generic_init_config
|
||||
proto_config_add_string "ip6addr"
|
||||
proto_config_add_string "peer6addr"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol vxlan
|
||||
add_protocol vxlan6
|
||||
}
|
||||
43
package/network/ipv6/6in4/Makefile
Normal file
43
package/network/ipv6/6in4/Makefile
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (C) 2010-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=6in4
|
||||
PKG_VERSION:=25
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/6in4
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=@IPV6 +kmod-sit +uclient-fetch
|
||||
TITLE:=IPv6-in-IPv4 configuration support
|
||||
MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/6in4/description
|
||||
Provides support for 6in4 tunnels in /etc/config/network.
|
||||
Refer to http://wiki.openwrt.org/doc/uci/network for
|
||||
configuration details.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/6in4/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/6in4.sh $(1)/lib/netifd/proto/6in4.sh
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,6in4))
|
||||
144
package/network/ipv6/6in4/files/6in4.sh
Executable file
144
package/network/ipv6/6in4/files/6in4.sh
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/bin/sh
|
||||
# 6in4.sh - IPv6-in-IPv4 tunnel backend
|
||||
# Copyright (c) 2010-2015 OpenWrt.org
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
proto_6in4_update() {
|
||||
sh -c '
|
||||
timeout=5
|
||||
|
||||
(while [ $((timeout--)) -gt 0 ]; do
|
||||
sleep 1
|
||||
kill -0 $$ || exit 0
|
||||
done; kill -9 $$) 2>/dev/null &
|
||||
|
||||
exec "$@"
|
||||
' "$1" "$@"
|
||||
}
|
||||
|
||||
proto_6in4_add_prefix() {
|
||||
append "$3" "$1"
|
||||
}
|
||||
|
||||
proto_6in4_setup() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
local link="6in4-$cfg"
|
||||
|
||||
local mtu ttl tos ipaddr peeraddr ip6addr ip6prefix ip6prefixes tunlink tunnelid username password updatekey
|
||||
json_get_vars mtu ttl tos ipaddr peeraddr ip6addr tunlink tunnelid username password updatekey
|
||||
json_for_each_item proto_6in4_add_prefix ip6prefix ip6prefixes
|
||||
|
||||
[ -z "$peeraddr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
return
|
||||
}
|
||||
|
||||
( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
|
||||
|
||||
[ -z "$ipaddr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z "$wanif" ] && ! network_find_wan wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr ipaddr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
proto_init_update "$link" 1
|
||||
|
||||
[ -n "$ip6addr" ] && {
|
||||
local local6="${ip6addr%%/*}"
|
||||
local mask6="${ip6addr##*/}"
|
||||
[[ "$local6" = "$mask6" ]] && mask6=
|
||||
proto_add_ipv6_address "$local6" "$mask6"
|
||||
proto_add_ipv6_route "::" 0 "" "" "" "$local6/$mask6"
|
||||
}
|
||||
|
||||
for ip6prefix in $ip6prefixes; do
|
||||
proto_add_ipv6_prefix "$ip6prefix"
|
||||
proto_add_ipv6_route "::" 0 "" "" "" "$ip6prefix"
|
||||
done
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode sit
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
json_add_int ttl "${ttl:-64}"
|
||||
[ -n "$tos" ] && json_add_string tos "$tos"
|
||||
json_add_string local "$ipaddr"
|
||||
json_add_string remote "$peeraddr"
|
||||
[ -n "$tunlink" ] && json_add_string link "$tunlink"
|
||||
proto_close_tunnel
|
||||
|
||||
proto_send_update "$cfg"
|
||||
|
||||
[ -n "$tunnelid" -a -n "$username" -a \( -n "$password" -o -n "$updatekey" \) ] && {
|
||||
[ -n "$updatekey" ] && password="$updatekey"
|
||||
|
||||
local http="http"
|
||||
local urlget="uclient-fetch"
|
||||
local urlget_opts="-qO-"
|
||||
local ca_path="${SSL_CERT_DIR:-/etc/ssl/certs}"
|
||||
|
||||
[ -f /lib/libustream-ssl.so ] && http=https
|
||||
[ "$http" = "https" -a -z "$(find $ca_path -name "*.0" 2>/dev/null)" ] && {
|
||||
urlget_opts="$urlget_opts --no-check-certificate"
|
||||
}
|
||||
|
||||
local url="$http://ipv4.tunnelbroker.net/nic/update?hostname=$tunnelid"
|
||||
local try=0
|
||||
local max=3
|
||||
|
||||
(
|
||||
set -o pipefail
|
||||
while [ $((++try)) -le $max ]; do
|
||||
if proto_6in4_update $urlget $urlget_opts --user="$username" --password="$password" "$url" 2>&1 | \
|
||||
sed -e 's,^Killed$,timeout,' -e "s,^,update $try/$max: ," | \
|
||||
logger -t "$link";
|
||||
then
|
||||
logger -t "$link" "updated"
|
||||
return 0
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
logger -t "$link" "update failed"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
proto_6in4_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_6in4_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_string "ip6addr"
|
||||
proto_config_add_array "ip6prefix"
|
||||
proto_config_add_string "peeraddr"
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_string "tunnelid"
|
||||
proto_config_add_string "username"
|
||||
proto_config_add_string "password"
|
||||
proto_config_add_string "updatekey"
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_string "tos"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol 6in4
|
||||
}
|
||||
49
package/network/ipv6/6rd/Makefile
Normal file
49
package/network/ipv6/6rd/Makefile
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# Copyright (C) 2010-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=6rd
|
||||
PKG_VERSION:=9
|
||||
PKG_RELEASE:=4
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/6rd
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=@IPV6 +kmod-sit
|
||||
TITLE:=6rd configuration support
|
||||
MAINTAINER:=Steven Barth <cyrus@openwrt.org>
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/6rd/description
|
||||
Provides support for 6rd tunnels in /etc/config/network.
|
||||
Refer to http://wiki.openwrt.org/doc/uci/network for
|
||||
configuration details.
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
CC="$(TARGET_CC)" \
|
||||
CFLAGS="$(TARGET_CFLAGS) -Wall" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS)"
|
||||
endef
|
||||
|
||||
define Package/6rd/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/6rdcalc $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/6rd.sh $(1)/lib/netifd/proto/6rd.sh
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,6rd))
|
||||
106
package/network/ipv6/6rd/files/6rd.sh
Normal file
106
package/network/ipv6/6rd/files/6rd.sh
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/bin/sh
|
||||
# 6rd.sh - IPv6-in-IPv4 tunnel backend
|
||||
# Copyright (c) 2010-2012 OpenWrt.org
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
proto_6rd_setup() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
local link="6rd-$cfg"
|
||||
|
||||
local mtu df ttl tos ipaddr peeraddr ip6prefix ip6prefixlen ip4prefixlen tunlink zone
|
||||
json_get_vars mtu df ttl tos ipaddr peeraddr ip6prefix ip6prefixlen ip4prefixlen tunlink zone
|
||||
|
||||
[ -z "$ip6prefix" -o -z "$peeraddr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
return
|
||||
}
|
||||
|
||||
( proto_add_host_dependency "$cfg" "$peeraddr" "$tunlink" )
|
||||
|
||||
[ -z "$ipaddr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z $wanif ] && ! network_find_wan wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr ipaddr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
# Determine the relay prefix.
|
||||
local ip4prefixlen="${ip4prefixlen:-0}"
|
||||
local ip4prefix
|
||||
eval "$(ipcalc.sh "$ipaddr/$ip4prefixlen")";ip4prefix=$NETWORK
|
||||
|
||||
# Determine our IPv6 address.
|
||||
local ip6subnet=$(6rdcalc "$ip6prefix/$ip6prefixlen" "$ipaddr/$ip4prefixlen")
|
||||
local ip6addr="${ip6subnet%%::*}::1"
|
||||
|
||||
# Determine the IPv6 prefix
|
||||
local ip6lanprefix="$ip6subnet/$(($ip6prefixlen + 32 - $ip4prefixlen))"
|
||||
|
||||
proto_init_update "$link" 1
|
||||
proto_add_ipv6_address "$ip6addr" "$ip6prefixlen"
|
||||
proto_add_ipv6_prefix "$ip6lanprefix"
|
||||
|
||||
proto_add_ipv6_route "::" 0 "::$peeraddr" 4096 "" "$ip6addr/$ip6prefixlen"
|
||||
proto_add_ipv6_route "::" 0 "::$peeraddr" 4096 "" "$ip6lanprefix"
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode sit
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
json_add_boolean df "${df:-1}"
|
||||
json_add_int ttl "${ttl:-64}"
|
||||
[ -n "$tos" ] && json_add_string tos "$tos"
|
||||
json_add_string local "$ipaddr"
|
||||
[ -n "$tunlink" ] && json_add_string link "$tunlink"
|
||||
|
||||
json_add_object 'data'
|
||||
json_add_string prefix "$ip6prefix/$ip6prefixlen"
|
||||
json_add_string relay-prefix "$ip4prefix/$ip4prefixlen"
|
||||
json_close_object
|
||||
|
||||
proto_close_tunnel
|
||||
|
||||
proto_add_data
|
||||
[ -n "$zone" ] && json_add_string zone "$zone"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$cfg"
|
||||
}
|
||||
|
||||
proto_6rd_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_6rd_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_boolean "df"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_string "tos"
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_string "peeraddr"
|
||||
proto_config_add_string "ip6prefix"
|
||||
proto_config_add_string "ip6prefixlen"
|
||||
proto_config_add_string "ip4prefixlen"
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_string "zone"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol 6rd
|
||||
}
|
||||
126
package/network/ipv6/6rd/src/6rdcalc.c
Normal file
126
package/network/ipv6/6rd/src/6rdcalc.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Utility used to calculate the 6rd subnet.
|
||||
*
|
||||
* Copyright 2012, Stéphan Kochen <stephan@kochen.nl>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define INET_PREFIXSTRLEN (INET_ADDRSTRLEN+3)
|
||||
#define INET6_PREFIXSTRLEN (INET6_ADDRSTRLEN+4)
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
fprintf(stderr, "Usage: 6rdcalc <v6 prefix>/<mask> <v4 address>/<mask>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void print_error()
|
||||
{
|
||||
fprintf(stderr, "%s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void parse_str(int af, char *str, void *addr, unsigned long *mask)
|
||||
{
|
||||
int ret;
|
||||
char *slash;
|
||||
|
||||
/* Split the address at the slash. */
|
||||
if ((slash = strchr(str, '/')) == NULL)
|
||||
print_usage();
|
||||
*slash = '\0';
|
||||
|
||||
/* Parse the address. */
|
||||
if ((ret = inet_pton(af, str, addr)) != 1) {
|
||||
if (ret == 0)
|
||||
print_usage();
|
||||
else
|
||||
print_error();
|
||||
}
|
||||
|
||||
/* Parse the mask. */
|
||||
*mask = strtoul(slash+1, NULL, 10);
|
||||
if ((af == AF_INET && *mask > 32) ||
|
||||
(af == AF_INET6 && *mask > 128))
|
||||
print_usage();
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
char v6str[INET6_PREFIXSTRLEN], v4str[INET_PREFIXSTRLEN];
|
||||
struct in6_addr v6;
|
||||
struct in_addr v4;
|
||||
unsigned long v6it, v4it, mask;
|
||||
unsigned char *byte4, *byte6;
|
||||
unsigned char bit4, bit6;
|
||||
|
||||
/* Check parameters. */
|
||||
if (argc != 3)
|
||||
print_usage();
|
||||
|
||||
/* Parse the v6 address. */
|
||||
strncpy(v6str, argv[1], INET6_PREFIXSTRLEN);
|
||||
v6str[INET6_PREFIXSTRLEN-1] = '\0';
|
||||
parse_str(AF_INET6, v6str, &v6, &v6it);
|
||||
|
||||
/* Parse the v4 address */
|
||||
strncpy(v4str, argv[2], INET_PREFIXSTRLEN);
|
||||
v6str[INET_PREFIXSTRLEN-1] = '\0';
|
||||
parse_str(AF_INET, v4str, &v4, &v4it);
|
||||
|
||||
/* Check if the combined mask is within bounds. */
|
||||
mask = (32 - v4it) + v6it;
|
||||
if (mask > 128)
|
||||
print_usage();
|
||||
|
||||
/* Combine the addresses. */
|
||||
while (v4it < 32) {
|
||||
byte6 = (unsigned char *)(&v6.s6_addr) + (v6it >> 3);
|
||||
byte4 = (unsigned char *)(&v4.s_addr) + (v4it >> 3);
|
||||
bit6 = 128 >> (v6it & 0x07);
|
||||
bit4 = 128 >> (v4it & 0x07);
|
||||
|
||||
if (*byte4 & bit4)
|
||||
*byte6 |= bit6;
|
||||
else
|
||||
*byte6 &= ~bit6;
|
||||
|
||||
v4it++; v6it++;
|
||||
}
|
||||
|
||||
/* Clear remaining bits. */
|
||||
while (v6it < 128) {
|
||||
byte6 = (unsigned char *)(&v6.s6_addr) + (v6it >> 3);
|
||||
bit6 = 128 >> (v6it & 0x07);
|
||||
|
||||
*byte6 &= ~bit6;
|
||||
|
||||
v6it++;
|
||||
}
|
||||
|
||||
/* Print the subnet prefix. */
|
||||
if (inet_ntop(AF_INET6, &v6, v6str, sizeof(v6str)) == NULL)
|
||||
print_error();
|
||||
printf("%s/%lu\n", v6str, mask);
|
||||
return 0;
|
||||
}
|
||||
7
package/network/ipv6/6rd/src/Makefile
Normal file
7
package/network/ipv6/6rd/src/Makefile
Normal file
@@ -0,0 +1,7 @@
|
||||
all: 6rdcalc
|
||||
|
||||
6rdcalc: 6rdcalc.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f 6rdcalc
|
||||
43
package/network/ipv6/6to4/Makefile
Normal file
43
package/network/ipv6/6to4/Makefile
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (C) 2010-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=6to4
|
||||
PKG_VERSION:=12
|
||||
PKG_RELEASE:=2
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/6to4
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=@IPV6 +kmod-sit
|
||||
TITLE:=IPv6-to-IPv4 configuration support
|
||||
MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/6to4/description
|
||||
Provides support for 6to4 tunnels in /etc/config/network.
|
||||
Refer to http://wiki.openwrt.org/doc/uci/network for
|
||||
configuration details.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/6to4/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/6to4.sh $(1)/lib/netifd/proto/6to4.sh
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,6to4))
|
||||
98
package/network/ipv6/6to4/files/6to4.sh
Executable file
98
package/network/ipv6/6to4/files/6to4.sh
Executable file
@@ -0,0 +1,98 @@
|
||||
#!/bin/sh
|
||||
# 6to4.sh - IPv6-in-IPv4 tunnel backend
|
||||
# Copyright (c) 2010-2012 OpenWrt.org
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
find_6to4_prefix() {
|
||||
local ip4="$1"
|
||||
local oIFS="$IFS"; IFS="."; set -- $ip4; IFS="$oIFS"
|
||||
|
||||
printf "2002:%02x%02x:%02x%02x\n" $1 $2 $3 $4
|
||||
}
|
||||
|
||||
test_6to4_rfc1918()
|
||||
{
|
||||
local oIFS="$IFS"; IFS="."; set -- $1; IFS="$oIFS"
|
||||
[ $1 -eq 10 ] && return 0
|
||||
[ $1 -eq 192 ] && [ $2 -eq 168 ] && return 0
|
||||
[ $1 -eq 172 ] && [ $2 -ge 16 ] && [ $2 -le 31 ] && return 0
|
||||
|
||||
# RFC 6598
|
||||
[ $1 -eq 100 ] && [ $2 -ge 64 ] && [ $2 -le 127 ] && return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
proto_6to4_setup() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
local link="6to4-$cfg"
|
||||
|
||||
local mtu ttl tos ipaddr
|
||||
json_get_vars mtu ttl tos ipaddr
|
||||
|
||||
( proto_add_host_dependency "$cfg" 0.0.0.0 )
|
||||
|
||||
local wanif
|
||||
if ! network_find_wan wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
|
||||
[ -z "$ipaddr" ] && {
|
||||
if ! network_get_ipaddr ipaddr "$wanif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_ADDRESS"
|
||||
return
|
||||
fi
|
||||
}
|
||||
|
||||
test_6to4_rfc1918 "$ipaddr" && {
|
||||
proto_notify_error "$cfg" "INVALID_LOCAL_ADDRESS"
|
||||
return
|
||||
}
|
||||
|
||||
# find our local prefix
|
||||
local prefix6=$(find_6to4_prefix "$ipaddr")
|
||||
local local6="$prefix6::1"
|
||||
|
||||
proto_init_update "$link" 1
|
||||
proto_add_ipv6_address "$local6" 16
|
||||
proto_add_ipv6_prefix "$prefix6::/48"
|
||||
|
||||
proto_add_ipv6_route "::" 0 "::192.88.99.1" "" "" "$local6/16"
|
||||
proto_add_ipv6_route "::" 0 "::192.88.99.1" "" "" "$prefix6::/48"
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode sit
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
json_add_int ttl "${ttl:-64}"
|
||||
[ -n "$tos" ] && json_add_string tos "$tos"
|
||||
json_add_string local "$ipaddr"
|
||||
proto_close_tunnel
|
||||
|
||||
proto_send_update "$cfg"
|
||||
}
|
||||
|
||||
proto_6to4_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_6to4_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_string "tos"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol 6to4
|
||||
}
|
||||
43
package/network/ipv6/ds-lite/Makefile
Normal file
43
package/network/ipv6/ds-lite/Makefile
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright (C) 2013 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ds-lite
|
||||
PKG_VERSION:=7
|
||||
PKG_RELEASE:=4
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/ds-lite
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=@IPV6 +kmod-ip6-tunnel +resolveip
|
||||
TITLE:=Dual-Stack Lite (DS-Lite) configuration support
|
||||
MAINTAINER:=Steven Barth <steven@midlink.org>
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/ds-lite/description
|
||||
Provides support for Dual-Stack Lite in /etc/config/network.
|
||||
Refer to http://wiki.openwrt.org/doc/uci/network for
|
||||
configuration details.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Package/ds-lite/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/dslite.sh $(1)/lib/netifd/proto/dslite.sh
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,ds-lite))
|
||||
110
package/network/ipv6/ds-lite/files/dslite.sh
Normal file
110
package/network/ipv6/ds-lite/files/dslite.sh
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/bin/sh
|
||||
# dslite.sh - IPv4-in-IPv6 tunnel backend
|
||||
# Copyright (c) 2013 OpenWrt.org
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
proto_dslite_setup() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
local link="ds-$cfg"
|
||||
local remoteip6
|
||||
|
||||
local mtu ttl peeraddr ip6addr tunlink zone weakif encaplimit
|
||||
json_get_vars mtu ttl peeraddr ip6addr tunlink zone weakif encaplimit
|
||||
|
||||
[ -z "$peeraddr" ] && {
|
||||
proto_notify_error "$cfg" "MISSING_ADDRESS"
|
||||
proto_block_restart "$cfg"
|
||||
return
|
||||
}
|
||||
|
||||
( proto_add_host_dependency "$cfg" "::" "$tunlink" )
|
||||
|
||||
remoteip6=$(resolveip -6 "$peeraddr")
|
||||
if [ -z "$remoteip6" ]; then
|
||||
sleep 3
|
||||
remoteip6=$(resolveip -6 "$peeraddr")
|
||||
if [ -z "$remoteip6" ]; then
|
||||
proto_notify_error "$cfg" "AFTR_DNS_FAIL"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
for ip6 in $remoteip6; do
|
||||
peeraddr=$ip6
|
||||
break
|
||||
done
|
||||
|
||||
[ -z "$ip6addr" ] && {
|
||||
local wanif="$tunlink"
|
||||
if [ -z "$wanif" ] && ! network_find_wan6 wanif; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! network_get_ipaddr6 ip6addr "$wanif"; then
|
||||
[ -z "$weakif" ] && weakif="lan"
|
||||
if ! network_get_ipaddr6 ip6addr "$weakif"; then
|
||||
proto_notify_error "$cfg" "NO_WAN_LINK"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
proto_init_update "$link" 1
|
||||
proto_add_ipv4_route "0.0.0.0" 0
|
||||
proto_add_ipv4_address "192.0.0.2" "" "" "192.0.0.1"
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode ipip6
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
json_add_int ttl "${ttl:-64}"
|
||||
json_add_string local "$ip6addr"
|
||||
json_add_string remote "$peeraddr"
|
||||
[ -n "$tunlink" ] && json_add_string link "$tunlink"
|
||||
json_add_object "data"
|
||||
[ -n "$encaplimit" ] && json_add_string encaplimit "$encaplimit"
|
||||
json_close_object
|
||||
proto_close_tunnel
|
||||
|
||||
proto_add_data
|
||||
[ -n "$zone" ] && json_add_string zone "$zone"
|
||||
|
||||
json_add_array firewall
|
||||
json_add_object ""
|
||||
json_add_string type nat
|
||||
json_add_string target ACCEPT
|
||||
json_close_object
|
||||
json_close_array
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$cfg"
|
||||
}
|
||||
|
||||
proto_dslite_teardown() {
|
||||
local cfg="$1"
|
||||
}
|
||||
|
||||
proto_dslite_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_string "ip6addr"
|
||||
proto_config_add_string "peeraddr"
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_string "encaplimit"
|
||||
proto_config_add_string "zone"
|
||||
proto_config_add_string "weakif"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol dslite
|
||||
}
|
||||
40
package/network/ipv6/map/Makefile
Normal file
40
package/network/ipv6/map/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (C) 2014-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=map
|
||||
PKG_VERSION:=4
|
||||
PKG_RELEASE:=12
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/map
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=@IPV6 +kmod-ip6-tunnel +libubox +libubus +iptables-mod-conntrack-extra
|
||||
TITLE:=MAP-E and Lightweight 4over6 configuration support
|
||||
MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
|
||||
endef
|
||||
|
||||
define Package/map/description
|
||||
Provides support for MAP-E (draft-ietf-softwire-map) and
|
||||
Lightweight 4over6 (draft-ietf-softwire-lw4over6) in /etc/config/network.
|
||||
Refer to http://wiki.openwrt.org/doc/uci/network for
|
||||
configuration details.
|
||||
endef
|
||||
|
||||
define Package/map/install
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/map.sh $(1)/lib/netifd/proto/map.sh
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mapcalc $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,map))
|
||||
238
package/network/ipv6/map/files/map.sh
Executable file
238
package/network/ipv6/map/files/map.sh
Executable file
@@ -0,0 +1,238 @@
|
||||
#!/bin/sh
|
||||
# map.sh - IPv4-in-IPv6 tunnel backend
|
||||
#
|
||||
# Author: Steven Barth <cyrus@openwrt.org>
|
||||
# Copyright (c) 2014 cisco Systems, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License version 2
|
||||
# as published by the Free Software Foundation
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
}
|
||||
|
||||
proto_map_setup() {
|
||||
local cfg="$1"
|
||||
local iface="$2"
|
||||
local link="map-$cfg"
|
||||
|
||||
# uncomment for legacy MAP0 mode
|
||||
#export LEGACY=1
|
||||
|
||||
local type mtu ttl tunlink zone encaplimit
|
||||
local rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
|
||||
json_get_vars type mtu ttl tunlink zone encaplimit
|
||||
json_get_vars rule ipaddr ip4prefixlen ip6prefix ip6prefixlen peeraddr ealen psidlen psid offset
|
||||
|
||||
[ -z "$zone" ] && zone="wan"
|
||||
[ -z "$type" ] && type="map-e"
|
||||
[ -z "$ip4prefixlen" ] && ip4prefixlen=32
|
||||
|
||||
( proto_add_host_dependency "$cfg" "::" "$tunlink" )
|
||||
|
||||
# fixme: handle RA/DHCPv6 address race for LW
|
||||
[ "$type" = lw4o6 ] && sleep 5
|
||||
|
||||
if [ -z "$rule" ]; then
|
||||
rule="type=$type,ipv6prefix=$ip6prefix,prefix6len=$ip6prefixlen,ipv4prefix=$ipaddr,prefix4len=$ip4prefixlen"
|
||||
[ -n "$psid" ] && rule="$rule,psid=$psid"
|
||||
[ -n "$psidlen" ] && rule="$rule,psidlen=$psidlen"
|
||||
[ -n "$offset" ] && rule="$rule,offset=$offset"
|
||||
[ -n "$ealen" ] && rule="$rule,ealen=$ealen"
|
||||
if [ "$type" = "map-t" ]; then
|
||||
rule="$rule,dmr=$peeraddr"
|
||||
else
|
||||
rule="$rule,br=$peeraddr"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "rule=$rule" > /tmp/map-$cfg.rules
|
||||
RULE_DATA=$(mapcalc ${tunlink:-\*} $rule)
|
||||
if [ "$?" != 0 ]; then
|
||||
proto_notify_error "$cfg" "INVALID_MAP_RULE"
|
||||
proto_block_restart "$cfg"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "$RULE_DATA" >> /tmp/map-$cfg.rules
|
||||
eval $RULE_DATA
|
||||
|
||||
if [ -z "$RULE_BMR" ]; then
|
||||
proto_notify_error "$cfg" "NO_MATCHING_PD"
|
||||
proto_block_restart "$cfg"
|
||||
return
|
||||
fi
|
||||
|
||||
k=$RULE_BMR
|
||||
if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
|
||||
proto_init_update "$link" 1
|
||||
proto_add_ipv4_address $(eval "echo \$RULE_${k}_IPV4ADDR") "" "" ""
|
||||
|
||||
proto_add_tunnel
|
||||
json_add_string mode ipip6
|
||||
json_add_int mtu "${mtu:-1280}"
|
||||
json_add_int ttl "${ttl:-64}"
|
||||
json_add_string local $(eval "echo \$RULE_${k}_IPV6ADDR")
|
||||
json_add_string remote $(eval "echo \$RULE_${k}_BR")
|
||||
json_add_string link $(eval "echo \$RULE_${k}_PD6IFACE")
|
||||
json_add_object "data"
|
||||
[ -n "$encaplimit" ] && json_add_string encaplimit "$encaplimit"
|
||||
if [ "$type" = "map-e" ]; then
|
||||
json_add_array "fmrs"
|
||||
for i in $(seq $RULE_COUNT); do
|
||||
[ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
|
||||
json_add_object ""
|
||||
json_add_string prefix6 "$(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
|
||||
json_add_string prefix4 "$(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
|
||||
json_add_int ealen $(eval "echo \$RULE_${i}_EALEN")
|
||||
json_add_int offset $(eval "echo \$RULE_${i}_OFFSET")
|
||||
json_close_object
|
||||
done
|
||||
json_close_array
|
||||
fi
|
||||
json_close_object
|
||||
|
||||
|
||||
proto_close_tunnel
|
||||
elif [ "$type" = "map-t" -a -f "/proc/net/nat46/control" ]; then
|
||||
proto_init_update "$link" 1
|
||||
local style="MAP"
|
||||
[ "$LEGACY" = 1 ] && style="MAP0"
|
||||
|
||||
echo add $link > /proc/net/nat46/control
|
||||
local cfgstr="local.style $style local.v4 $(eval "echo \$RULE_${k}_IPV4PREFIX")/$(eval "echo \$RULE_${k}_PREFIX4LEN")"
|
||||
cfgstr="$cfgstr local.v6 $(eval "echo \$RULE_${k}_IPV6PREFIX")/$(eval "echo \$RULE_${k}_PREFIX6LEN")"
|
||||
cfgstr="$cfgstr local.ea-len $(eval "echo \$RULE_${k}_EALEN") local.psid-offset $(eval "echo \$RULE_${k}_OFFSET")"
|
||||
cfgstr="$cfgstr remote.v4 0.0.0.0/0 remote.v6 $(eval "echo \$RULE_${k}_DMR") remote.style RFC6052 remote.ea-len 0 remote.psid-offset 0"
|
||||
echo config $link $cfgstr > /proc/net/nat46/control
|
||||
|
||||
for i in $(seq $RULE_COUNT); do
|
||||
[ "$(eval "echo \$RULE_${i}_FMR")" != 1 ] && continue
|
||||
local cfgstr="remote.style $style remote.v4 $(eval "echo \$RULE_${i}_IPV4PREFIX")/$(eval "echo \$RULE_${i}_PREFIX4LEN")"
|
||||
cfgstr="$cfgstr remote.v6 $(eval "echo \$RULE_${i}_IPV6PREFIX")/$(eval "echo \$RULE_${i}_PREFIX6LEN")"
|
||||
cfgstr="$cfgstr remote.ea-len $(eval "echo \$RULE_${i}_EALEN") remote.psid-offset $(eval "echo \$RULE_${i}_OFFSET")"
|
||||
echo insert $link $cfgstr > /proc/net/nat46/control
|
||||
done
|
||||
else
|
||||
proto_notify_error "$cfg" "UNSUPPORTED_TYPE"
|
||||
proto_block_restart "$cfg"
|
||||
fi
|
||||
|
||||
proto_add_ipv4_route "0.0.0.0" 0
|
||||
proto_add_data
|
||||
[ "$zone" != "-" ] && json_add_string zone "$zone"
|
||||
|
||||
json_add_array firewall
|
||||
if [ -z "$(eval "echo \$RULE_${k}_PORTSETS")" ]; then
|
||||
json_add_object ""
|
||||
json_add_string type nat
|
||||
json_add_string target SNAT
|
||||
json_add_string family inet
|
||||
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
|
||||
json_close_object
|
||||
else
|
||||
for portset in $(eval "echo \$RULE_${k}_PORTSETS"); do
|
||||
for proto in icmp tcp udp; do
|
||||
json_add_object ""
|
||||
json_add_string type nat
|
||||
json_add_string target SNAT
|
||||
json_add_string family inet
|
||||
json_add_string proto "$proto"
|
||||
json_add_boolean connlimit_ports 1
|
||||
json_add_string snat_ip $(eval "echo \$RULE_${k}_IPV4ADDR")
|
||||
json_add_string snat_port "$portset"
|
||||
json_close_object
|
||||
done
|
||||
done
|
||||
fi
|
||||
if [ "$type" = "map-t" ]; then
|
||||
json_add_object ""
|
||||
json_add_string type rule
|
||||
json_add_string family inet6
|
||||
json_add_string proto all
|
||||
json_add_string direction in
|
||||
json_add_string dest "$zone"
|
||||
json_add_string src "$zone"
|
||||
json_add_string src_ip $(eval "echo \$RULE_${k}_IPV6ADDR")
|
||||
json_add_string target ACCEPT
|
||||
json_close_object
|
||||
json_add_object ""
|
||||
json_add_string type rule
|
||||
json_add_string family inet6
|
||||
json_add_string proto all
|
||||
json_add_string direction out
|
||||
json_add_string dest "$zone"
|
||||
json_add_string src "$zone"
|
||||
json_add_string dest_ip $(eval "echo \$RULE_${k}_IPV6ADDR")
|
||||
json_add_string target ACCEPT
|
||||
json_close_object
|
||||
proto_add_ipv6_route $(eval "echo \$RULE_${k}_IPV6ADDR") 128
|
||||
fi
|
||||
json_close_array
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$cfg"
|
||||
|
||||
if [ "$type" = "lw4o6" -o "$type" = "map-e" ]; then
|
||||
json_init
|
||||
json_add_string name "${cfg}_"
|
||||
json_add_string ifname "@$(eval "echo \$RULE_${k}_PD6IFACE")"
|
||||
json_add_string proto "static"
|
||||
json_add_array ip6addr
|
||||
json_add_string "" "$(eval "echo \$RULE_${k}_IPV6ADDR")"
|
||||
json_close_array
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
fi
|
||||
}
|
||||
|
||||
proto_map_teardown() {
|
||||
local cfg="$1"
|
||||
local link="map-$cfg"
|
||||
|
||||
json_get_var type type
|
||||
|
||||
[ -z "$type" ] && type="map-e"
|
||||
|
||||
case "$type" in
|
||||
"map-e"|"lw4o6") ifdown "${cfg}_" ;;
|
||||
"map-t") [ -f "/proc/net/nat46/control" ] && echo del $link > /proc/net/nat46/control ;;
|
||||
esac
|
||||
|
||||
rm -f /tmp/map-$cfg.rules
|
||||
}
|
||||
|
||||
proto_map_init_config() {
|
||||
no_device=1
|
||||
available=1
|
||||
|
||||
proto_config_add_string "rule"
|
||||
proto_config_add_string "ipaddr"
|
||||
proto_config_add_int "ip4prefixlen"
|
||||
proto_config_add_string "ip6prefix"
|
||||
proto_config_add_int "ip6prefixlen"
|
||||
proto_config_add_string "peeraddr"
|
||||
proto_config_add_int "ealen"
|
||||
proto_config_add_int "psidlen"
|
||||
proto_config_add_int "psid"
|
||||
proto_config_add_int "offset"
|
||||
|
||||
proto_config_add_string "tunlink"
|
||||
proto_config_add_int "mtu"
|
||||
proto_config_add_int "ttl"
|
||||
proto_config_add_string "zone"
|
||||
proto_config_add_string "encaplimit"
|
||||
}
|
||||
|
||||
[ -n "$INCLUDE_ONLY" ] || {
|
||||
add_protocol map
|
||||
}
|
||||
29
package/network/ipv6/map/src/CMakeLists.txt
Normal file
29
package/network/ipv6/map/src/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
cmake_minimum_required(VERSION 2.8.1)
|
||||
|
||||
project(mapcalc C)
|
||||
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -std=c99")
|
||||
|
||||
FIND_PATH(ubus_include_dir libubus.h)
|
||||
INCLUDE_DIRECTORIES(${ubus_include_dir})
|
||||
|
||||
add_definitions(-D_GNU_SOURCE -Wall -Wno-gnu -Wextra)
|
||||
|
||||
add_executable(mapcalc mapcalc.c)
|
||||
target_link_libraries(mapcalc ubus ubox)
|
||||
|
||||
install(TARGETS mapcalc DESTINATION sbin/)
|
||||
|
||||
|
||||
# Packaging rules
|
||||
set(CPACK_PACKAGE_VERSION "1")
|
||||
set(CPACK_PACKAGE_CONTACT "Steven Barth <steven@midlink.org>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "hnetd")
|
||||
set(CPACK_GENERATOR "DEB;RPM;STGZ")
|
||||
set(CPACK_STRIP_FILES true)
|
||||
|
||||
SET(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}")
|
||||
|
||||
include(CPack)
|
||||
418
package/network/ipv6/map/src/mapcalc.c
Normal file
418
package/network/ipv6/map/src/mapcalc.c
Normal file
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* mapcalc - MAP parameter calculation
|
||||
*
|
||||
* Author: Steven Barth <cyrus@openwrt.org>
|
||||
* Copyright (c) 2014-2015 cisco Systems, Inc.
|
||||
* Copyright (c) 2015 Steven Barth <cyrus@openwrt.org>
|
||||
* Copyright (c) 2018 Hans Dedecker <dedeckeh@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <libubus.h>
|
||||
#include <libubox/utils.h>
|
||||
|
||||
|
||||
struct blob_attr *dump = NULL;
|
||||
|
||||
enum {
|
||||
DUMP_ATTR_INTERFACE,
|
||||
DUMP_ATTR_MAX
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy dump_attrs[DUMP_ATTR_MAX] = {
|
||||
[DUMP_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_ARRAY },
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
IFACE_ATTR_INTERFACE,
|
||||
IFACE_ATTR_PREFIX,
|
||||
IFACE_ATTR_ADDRESS,
|
||||
IFACE_ATTR_MAX,
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = {
|
||||
[IFACE_ATTR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
|
||||
[IFACE_ATTR_PREFIX] = { .name = "ipv6-prefix", .type = BLOBMSG_TYPE_ARRAY },
|
||||
[IFACE_ATTR_ADDRESS] = { .name = "ipv6-address", .type = BLOBMSG_TYPE_ARRAY },
|
||||
};
|
||||
|
||||
|
||||
enum {
|
||||
PREFIX_ATTR_ADDRESS,
|
||||
PREFIX_ATTR_MASK,
|
||||
PREFIX_ATTR_MAX,
|
||||
};
|
||||
|
||||
static const struct blobmsg_policy prefix_attrs[PREFIX_ATTR_MAX] = {
|
||||
[PREFIX_ATTR_ADDRESS] = { .name = "address", .type = BLOBMSG_TYPE_STRING },
|
||||
[PREFIX_ATTR_MASK] = { .name = "mask", .type = BLOBMSG_TYPE_INT32 },
|
||||
};
|
||||
|
||||
static int bmemcmp(const void *av, const void *bv, size_t bits)
|
||||
{
|
||||
const uint8_t *a = av, *b = bv;
|
||||
size_t bytes = bits / 8;
|
||||
bits %= 8;
|
||||
|
||||
int res = memcmp(a, b, bytes);
|
||||
if (res == 0 && bits > 0)
|
||||
res = (a[bytes] >> (8 - bits)) - (b[bytes] >> (8 - bits));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void bmemcpy(void *av, const void *bv, size_t bits)
|
||||
{
|
||||
uint8_t *a = av;
|
||||
const uint8_t *b = bv;
|
||||
|
||||
size_t bytes = bits / 8;
|
||||
bits %= 8;
|
||||
memcpy(a, b, bytes);
|
||||
|
||||
if (bits > 0) {
|
||||
uint8_t mask = (1 << (8 - bits)) - 1;
|
||||
a[bytes] = (a[bytes] & mask) | ((~mask) & b[bytes]);
|
||||
}
|
||||
}
|
||||
|
||||
static void bmemcpys64(void *av, const void *bv, size_t frombits, size_t nbits)
|
||||
{
|
||||
uint64_t buf = 0;
|
||||
const uint8_t *b = bv;
|
||||
size_t frombyte = frombits / 8, tobyte = (frombits + nbits) / 8;
|
||||
|
||||
memcpy(&buf, &b[frombyte], tobyte - frombyte + 1);
|
||||
buf = cpu_to_be64(be64_to_cpu(buf) << (frombits % 8));
|
||||
|
||||
bmemcpy(av, &buf, nbits);
|
||||
}
|
||||
|
||||
static void handle_dump(struct ubus_request *req __attribute__((unused)),
|
||||
int type __attribute__((unused)), struct blob_attr *msg)
|
||||
{
|
||||
struct blob_attr *tb[DUMP_ATTR_INTERFACE];
|
||||
blobmsg_parse(dump_attrs, DUMP_ATTR_MAX, tb, blob_data(msg), blob_len(msg));
|
||||
|
||||
if (!tb[DUMP_ATTR_INTERFACE])
|
||||
return;
|
||||
|
||||
dump = blob_memdup(tb[DUMP_ATTR_INTERFACE]);
|
||||
}
|
||||
|
||||
static void match_prefix(int *pdlen, struct in6_addr *pd, struct blob_attr *cur,
|
||||
const struct in6_addr *ipv6prefix, int prefix6len, bool lw4o6)
|
||||
{
|
||||
struct blob_attr *d;
|
||||
unsigned drem;
|
||||
|
||||
if (!cur || blobmsg_type(cur) != BLOBMSG_TYPE_ARRAY || !blobmsg_check_attr(cur, false))
|
||||
return;
|
||||
|
||||
blobmsg_for_each_attr(d, cur, drem) {
|
||||
struct blob_attr *ptb[PREFIX_ATTR_MAX];
|
||||
blobmsg_parse(prefix_attrs, PREFIX_ATTR_MAX, ptb,
|
||||
blobmsg_data(d), blobmsg_data_len(d));
|
||||
|
||||
if (!ptb[PREFIX_ATTR_ADDRESS] || !ptb[PREFIX_ATTR_MASK])
|
||||
continue;
|
||||
|
||||
struct in6_addr prefix = IN6ADDR_ANY_INIT;
|
||||
int mask = blobmsg_get_u32(ptb[PREFIX_ATTR_MASK]);
|
||||
inet_pton(AF_INET6, blobmsg_get_string(ptb[PREFIX_ATTR_ADDRESS]), &prefix);
|
||||
|
||||
// lw4over6 /128-address-as-PD matching madness workaround
|
||||
if (lw4o6 && mask == 128)
|
||||
mask = 64;
|
||||
|
||||
if (*pdlen < mask && mask >= prefix6len &&
|
||||
!bmemcmp(&prefix, ipv6prefix, prefix6len)) {
|
||||
bmemcpy(pd, &prefix, mask);
|
||||
*pdlen = mask;
|
||||
} else if (lw4o6 && *pdlen < prefix6len && mask < prefix6len &&
|
||||
!bmemcmp(&prefix, ipv6prefix, mask)) {
|
||||
bmemcpy(pd, ipv6prefix, prefix6len);
|
||||
*pdlen = prefix6len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
OPT_TYPE,
|
||||
OPT_FMR,
|
||||
OPT_EALEN,
|
||||
OPT_PREFIX4LEN,
|
||||
OPT_PREFIX6LEN,
|
||||
OPT_IPV6PREFIX,
|
||||
OPT_IPV4PREFIX,
|
||||
OPT_OFFSET,
|
||||
OPT_PSIDLEN,
|
||||
OPT_PSID,
|
||||
OPT_BR,
|
||||
OPT_DMR,
|
||||
OPT_PD,
|
||||
OPT_PDLEN,
|
||||
OPT_MAX
|
||||
};
|
||||
|
||||
static char *const token[] = {
|
||||
[OPT_TYPE] = "type",
|
||||
[OPT_FMR] = "fmr",
|
||||
[OPT_EALEN] = "ealen",
|
||||
[OPT_PREFIX4LEN] = "prefix4len",
|
||||
[OPT_PREFIX6LEN] = "prefix6len",
|
||||
[OPT_IPV6PREFIX] = "ipv6prefix",
|
||||
[OPT_IPV4PREFIX] = "ipv4prefix",
|
||||
[OPT_OFFSET] = "offset",
|
||||
[OPT_PSIDLEN] = "psidlen",
|
||||
[OPT_PSID] = "psid",
|
||||
[OPT_BR] = "br",
|
||||
[OPT_DMR] = "dmr",
|
||||
[OPT_PD] = "pd",
|
||||
[OPT_PDLEN] = "pdlen",
|
||||
[OPT_MAX] = NULL
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int status = 0;
|
||||
const char *iface = argv[1];
|
||||
|
||||
const char *legacy_env = getenv("LEGACY");
|
||||
bool legacy = legacy_env && atoi(legacy_env);
|
||||
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <interface|*> <rule1> [rule2] [...]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t network_interface;
|
||||
struct ubus_context *ubus = ubus_connect(NULL);
|
||||
if (ubus) {
|
||||
ubus_lookup_id(ubus, "network.interface", &network_interface);
|
||||
ubus_invoke(ubus, network_interface, "dump", NULL, handle_dump, NULL, 5000);
|
||||
}
|
||||
|
||||
int rulecnt = 0;
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
bool lw4o6 = false;
|
||||
bool fmr = false;
|
||||
int ealen = -1;
|
||||
int addr4len = 32;
|
||||
int prefix4len = 32;
|
||||
int prefix6len = -1;
|
||||
int pdlen = -1;
|
||||
struct in_addr ipv4prefix = {INADDR_ANY};
|
||||
struct in_addr ipv4addr = {INADDR_ANY};
|
||||
struct in6_addr ipv6addr = IN6ADDR_ANY_INIT;
|
||||
struct in6_addr ipv6prefix = IN6ADDR_ANY_INIT;
|
||||
struct in6_addr pd = IN6ADDR_ANY_INIT;
|
||||
int offset = -1;
|
||||
int psidlen = -1;
|
||||
int psid = -1;
|
||||
uint16_t psid16 = 0;
|
||||
const char *dmr = NULL;
|
||||
const char *br = NULL;
|
||||
|
||||
for (char *rule = strdup(argv[i]); *rule; ) {
|
||||
char *value;
|
||||
int intval;
|
||||
int idx = getsubopt(&rule, token, &value);
|
||||
errno = 0;
|
||||
|
||||
if (idx == OPT_TYPE) {
|
||||
lw4o6 = (value && !strcmp(value, "lw4o6"));
|
||||
} else if (idx == OPT_FMR) {
|
||||
fmr = true;
|
||||
} else if (idx == OPT_EALEN && (intval = strtoul(value, NULL, 0)) <= 48 && !errno) {
|
||||
ealen = intval;
|
||||
} else if (idx == OPT_PREFIX4LEN && (intval = strtoul(value, NULL, 0)) <= 32 && !errno) {
|
||||
prefix4len = intval;
|
||||
} else if (idx == OPT_PREFIX6LEN && (intval = strtoul(value, NULL, 0)) <= 128 && !errno) {
|
||||
prefix6len = intval;
|
||||
} else if (idx == OPT_IPV4PREFIX && inet_pton(AF_INET, value, &ipv4prefix) == 1) {
|
||||
// dummy
|
||||
} else if (idx == OPT_IPV6PREFIX && inet_pton(AF_INET6, value, &ipv6prefix) == 1) {
|
||||
// dummy
|
||||
} else if (idx == OPT_PD && inet_pton(AF_INET6, value, &pd) == 1) {
|
||||
// dummy
|
||||
} else if (idx == OPT_OFFSET && (intval = strtoul(value, NULL, 0)) <= 16 && !errno) {
|
||||
offset = intval;
|
||||
} else if (idx == OPT_PSIDLEN && (intval = strtoul(value, NULL, 0)) <= 16 && !errno) {
|
||||
psidlen = intval;
|
||||
} else if (idx == OPT_PDLEN && (intval = strtoul(value, NULL, 0)) <= 128 && !errno) {
|
||||
pdlen = intval;
|
||||
} else if (idx == OPT_PSID && (intval = strtoul(value, NULL, 0)) <= 65535 && !errno) {
|
||||
psid = intval;
|
||||
} else if (idx == OPT_DMR) {
|
||||
dmr = value;
|
||||
} else if (idx == OPT_BR) {
|
||||
br = value;
|
||||
} else {
|
||||
if (idx == -1 || idx >= OPT_MAX)
|
||||
fprintf(stderr, "Skipped invalid option: %s\n", value);
|
||||
else
|
||||
fprintf(stderr, "Skipped invalid value %s for option %s\n",
|
||||
value, token[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
if (offset < 0)
|
||||
offset = (lw4o6) ? 0 : (legacy) ? 4 : 6;
|
||||
|
||||
// LW4over6 doesn't have an EALEN and has no psid-autodetect
|
||||
if (lw4o6) {
|
||||
if (psidlen < 0)
|
||||
psidlen = 0;
|
||||
|
||||
ealen = psidlen;
|
||||
}
|
||||
|
||||
// Find PD
|
||||
if (pdlen < 0) {
|
||||
struct blob_attr *c;
|
||||
unsigned rem;
|
||||
blobmsg_for_each_attr(c, dump, rem) {
|
||||
struct blob_attr *tb[IFACE_ATTR_MAX];
|
||||
blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blobmsg_data(c), blobmsg_data_len(c));
|
||||
|
||||
if (!tb[IFACE_ATTR_INTERFACE] || (strcmp(argv[1], "*") && strcmp(argv[1],
|
||||
blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]))))
|
||||
continue;
|
||||
|
||||
match_prefix(&pdlen, &pd, tb[IFACE_ATTR_PREFIX], &ipv6prefix, prefix6len, lw4o6);
|
||||
|
||||
if (lw4o6)
|
||||
match_prefix(&pdlen, &pd, tb[IFACE_ATTR_ADDRESS], &ipv6prefix, prefix6len, lw4o6);
|
||||
|
||||
if (pdlen >= 0) {
|
||||
iface = blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ealen < 0 && pdlen >= 0)
|
||||
ealen = pdlen - prefix6len;
|
||||
|
||||
if (psidlen <= 0) {
|
||||
psidlen = ealen - (32 - prefix4len);
|
||||
if (psidlen < 0)
|
||||
psidlen = 0;
|
||||
|
||||
psid = -1;
|
||||
}
|
||||
|
||||
if (prefix4len < 0 || prefix6len < 0 || ealen < 0 || psidlen > 16 || ealen < psidlen) {
|
||||
fprintf(stderr, "Skipping invalid or incomplete rule: %s\n", argv[i]);
|
||||
status = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (psid < 0 && psidlen >= 0 && pdlen >= 0) {
|
||||
bmemcpys64(&psid16, &pd, prefix6len + ealen - psidlen, psidlen);
|
||||
psid = be16_to_cpu(psid16);
|
||||
}
|
||||
|
||||
if (psidlen > 0) {
|
||||
psid = psid >> (16 - psidlen);
|
||||
psid16 = cpu_to_be16(psid);
|
||||
psid = psid << (16 - psidlen);
|
||||
}
|
||||
|
||||
if (pdlen >= 0 || ealen == psidlen) {
|
||||
bmemcpys64(&ipv4addr, &pd, prefix6len, ealen - psidlen);
|
||||
ipv4addr.s_addr = htonl(ntohl(ipv4addr.s_addr) >> prefix4len);
|
||||
bmemcpy(&ipv4addr, &ipv4prefix, prefix4len);
|
||||
|
||||
if (prefix4len + ealen < 32)
|
||||
addr4len = prefix4len + ealen;
|
||||
}
|
||||
|
||||
if (pdlen < 0 && !fmr) {
|
||||
fprintf(stderr, "Skipping non-FMR without matching PD: %s\n", argv[i]);
|
||||
status = 1;
|
||||
continue;
|
||||
} else if (pdlen >= 0) {
|
||||
size_t v4offset = (legacy) ? 9 : 10;
|
||||
memcpy(&ipv6addr.s6_addr[v4offset], &ipv4addr, 4);
|
||||
memcpy(&ipv6addr.s6_addr[v4offset + 4], &psid16, 2);
|
||||
bmemcpy(&ipv6addr, &pd, pdlen);
|
||||
}
|
||||
|
||||
++rulecnt;
|
||||
char ipv4addrbuf[INET_ADDRSTRLEN];
|
||||
char ipv4prefixbuf[INET_ADDRSTRLEN];
|
||||
char ipv6prefixbuf[INET6_ADDRSTRLEN];
|
||||
char ipv6addrbuf[INET6_ADDRSTRLEN];
|
||||
char pdbuf[INET6_ADDRSTRLEN];
|
||||
|
||||
inet_ntop(AF_INET, &ipv4addr, ipv4addrbuf, sizeof(ipv4addrbuf));
|
||||
inet_ntop(AF_INET, &ipv4prefix, ipv4prefixbuf, sizeof(ipv4prefixbuf));
|
||||
inet_ntop(AF_INET6, &ipv6prefix, ipv6prefixbuf, sizeof(ipv6prefixbuf));
|
||||
inet_ntop(AF_INET6, &ipv6addr, ipv6addrbuf, sizeof(ipv6addrbuf));
|
||||
inet_ntop(AF_INET6, &pd, pdbuf, sizeof(pdbuf));
|
||||
|
||||
printf("RULE_%d_FMR=%d\n", rulecnt, fmr);
|
||||
printf("RULE_%d_EALEN=%d\n", rulecnt, ealen);
|
||||
printf("RULE_%d_PSIDLEN=%d\n", rulecnt, psidlen);
|
||||
printf("RULE_%d_OFFSET=%d\n", rulecnt, offset);
|
||||
printf("RULE_%d_PREFIX4LEN=%d\n", rulecnt, prefix4len);
|
||||
printf("RULE_%d_PREFIX6LEN=%d\n", rulecnt, prefix6len);
|
||||
printf("RULE_%d_IPV4PREFIX=%s\n", rulecnt, ipv4prefixbuf);
|
||||
printf("RULE_%d_IPV6PREFIX=%s\n", rulecnt, ipv6prefixbuf);
|
||||
|
||||
if (pdlen >= 0) {
|
||||
printf("RULE_%d_IPV6PD=%s\n", rulecnt, pdbuf);
|
||||
printf("RULE_%d_PD6LEN=%d\n", rulecnt, pdlen);
|
||||
printf("RULE_%d_PD6IFACE=%s\n", rulecnt, iface);
|
||||
printf("RULE_%d_IPV6ADDR=%s\n", rulecnt, ipv6addrbuf);
|
||||
printf("RULE_BMR=%d\n", rulecnt);
|
||||
}
|
||||
|
||||
if (ipv4addr.s_addr) {
|
||||
printf("RULE_%d_IPV4ADDR=%s\n", rulecnt, ipv4addrbuf);
|
||||
printf("RULE_%d_ADDR4LEN=%d\n", rulecnt, addr4len);
|
||||
}
|
||||
|
||||
|
||||
if (psidlen > 0 && psid >= 0) {
|
||||
printf("RULE_%d_PORTSETS='", rulecnt);
|
||||
for (int k = (offset) ? 1 : 0; k < (1 << offset); ++k) {
|
||||
int start = (k << (16 - offset)) | (psid >> offset);
|
||||
int end = start + (1 << (16 - offset - psidlen)) - 1;
|
||||
|
||||
if (start == 0)
|
||||
start = 1;
|
||||
|
||||
if (start <= end)
|
||||
printf("%d-%d ", start, end);
|
||||
}
|
||||
printf("'\n");
|
||||
}
|
||||
|
||||
if (dmr)
|
||||
printf("RULE_%d_DMR=%s\n", rulecnt, dmr);
|
||||
|
||||
if (br)
|
||||
printf("RULE_%d_BR=%s\n", rulecnt, br);
|
||||
}
|
||||
|
||||
printf("RULE_COUNT=%d\n", rulecnt);
|
||||
return status;
|
||||
}
|
||||
53
package/network/ipv6/odhcp6c/Makefile
Normal file
53
package/network/ipv6/odhcp6c/Makefile
Normal file
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Copyright (C) 2012-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=odhcp6c
|
||||
PKG_RELEASE:=15
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL=$(PROJECT_GIT)/project/odhcp6c.git
|
||||
PKG_SOURCE_DATE:=2018-07-14
|
||||
PKG_SOURCE_VERSION:=67ae6a71b5762292e114b281d0e329cc24209ae6
|
||||
PKG_MIRROR_HASH:=176b637b3856af0d6bb9c526afbddca4e569ea056fc36fc026345e7e22a6cef5
|
||||
PKG_MAINTAINER:=Hans Dedecker <dedeckeh@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
CMAKE_OPTIONS += \
|
||||
-DUSE_LIBUBOX=on
|
||||
|
||||
ifneq ($(CONFIG_PACKAGE_odhcp6c_ext_cer_id),0)
|
||||
CMAKE_OPTIONS += -DEXT_CER_ID=$(CONFIG_PACKAGE_odhcp6c_ext_cer_id)
|
||||
endif
|
||||
|
||||
define Package/odhcp6c
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Embedded DHCPv6-client for OpenWrt
|
||||
DEPENDS:=@IPV6 +libubox
|
||||
endef
|
||||
|
||||
define Package/odhcp6c/config
|
||||
config PACKAGE_odhcp6c_ext_cer_id
|
||||
int "CER-ID Extension ID (0 = disabled)"
|
||||
depends on PACKAGE_odhcp6c
|
||||
default 0
|
||||
endef
|
||||
|
||||
define Package/odhcp6c/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin/
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/odhcp6c $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/lib/netifd/proto
|
||||
$(INSTALL_BIN) ./files/dhcpv6.sh $(1)/lib/netifd/proto/dhcpv6.sh
|
||||
$(INSTALL_BIN) ./files/dhcpv6.script $(1)/lib/netifd/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,odhcp6c))
|
||||
241
package/network/ipv6/odhcp6c/files/dhcpv6.script
Executable file
241
package/network/ipv6/odhcp6c/files/dhcpv6.script
Executable file
@@ -0,0 +1,241 @@
|
||||
#!/bin/sh
|
||||
[ -z "$2" ] && echo "Error: should be run by odhcpc6c" && exit 1
|
||||
. /lib/functions.sh
|
||||
. /lib/netifd/netifd-proto.sh
|
||||
|
||||
setup_interface () {
|
||||
local device="$1"
|
||||
local prefsig=""
|
||||
local addrsig=""
|
||||
|
||||
# Apply IPv6 / ND configuration
|
||||
HOPLIMIT=$(cat /proc/sys/net/ipv6/conf/$device/hop_limit)
|
||||
[ -n "$RA_HOPLIMIT" -a -n "$HOPLIMIT" ] && [ "$RA_HOPLIMIT" -gt "$HOPLIMIT" ] && echo "$RA_HOPLIMIT" > /proc/sys/net/ipv6/conf/$device/hop_limit
|
||||
[ -n "$RA_MTU" ] && [ "$RA_MTU" -ge 1280 ] && echo "$RA_MTU" > /proc/sys/net/ipv6/conf/$device/mtu 2>/dev/null
|
||||
[ -n "$RA_REACHABLE" ] && [ "$RA_REACHABLE" -gt 0 ] && echo "$RA_REACHABLE" > /proc/sys/net/ipv6/neigh/$device/base_reachable_time_ms
|
||||
[ -n "$RA_RETRANSMIT" ] && [ "$RA_RETRANSMIT" -gt 0 ] && echo "$RA_RETRANSMIT" > /proc/sys/net/ipv6/neigh/$device/retrans_time_ms
|
||||
|
||||
proto_init_update "*" 1
|
||||
|
||||
# Merge RA-DNS
|
||||
for radns in $RA_DNS; do
|
||||
local duplicate=0
|
||||
for dns in $RDNSS; do
|
||||
[ "$radns" = "$dns" ] && duplicate=1
|
||||
done
|
||||
[ "$duplicate" = 0 ] && RDNSS="$RDNSS $radns"
|
||||
done
|
||||
|
||||
for dns in $RDNSS; do
|
||||
proto_add_dns_server "$dns"
|
||||
done
|
||||
|
||||
for radomain in $RA_DOMAINS; do
|
||||
local duplicate=0
|
||||
for domain in $DOMAINS; do
|
||||
[ "$radomain" = "$domain" ] && duplicate=1
|
||||
done
|
||||
[ "$duplicate" = 0 ] && DOMAINS="$DOMAINS $radomain"
|
||||
done
|
||||
|
||||
for domain in $DOMAINS; do
|
||||
proto_add_dns_search "$domain"
|
||||
done
|
||||
|
||||
for prefix in $PREFIXES; do
|
||||
proto_add_ipv6_prefix "$prefix"
|
||||
prefsig="$prefsig ${prefix%%,*}"
|
||||
local entry="${prefix#*/}"
|
||||
entry="${entry#*,}"
|
||||
entry="${entry#*,}"
|
||||
local valid="${entry%%,*}"
|
||||
|
||||
if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
|
||||
-z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
|
||||
RA_ROUTES="::/0,$SERVER,$valid,4096"
|
||||
fi
|
||||
done
|
||||
|
||||
for prefix in $USERPREFIX; do
|
||||
proto_add_ipv6_prefix "$prefix"
|
||||
done
|
||||
|
||||
# Merge addresses
|
||||
for entry in $RA_ADDRESSES; do
|
||||
local duplicate=0
|
||||
local addr="${entry%%/*}"
|
||||
for dentry in $ADDRESSES; do
|
||||
local daddr="${dentry%%/*}"
|
||||
[ "$addr" = "$daddr" ] && duplicate=1
|
||||
done
|
||||
[ "$duplicate" = "0" ] && ADDRESSES="$ADDRESSES $entry"
|
||||
done
|
||||
|
||||
for entry in $ADDRESSES; do
|
||||
local addr="${entry%%/*}"
|
||||
entry="${entry#*/}"
|
||||
local mask="${entry%%,*}"
|
||||
entry="${entry#*,}"
|
||||
local preferred="${entry%%,*}"
|
||||
entry="${entry#*,}"
|
||||
local valid="${entry%%,*}"
|
||||
|
||||
proto_add_ipv6_address "$addr" "$mask" "$preferred" "$valid" 1
|
||||
addrsig="$addrsig $addr/$mask"
|
||||
|
||||
if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
|
||||
-z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
|
||||
RA_ROUTES="::/0,$SERVER,$valid,4096"
|
||||
fi
|
||||
|
||||
# RFC 7278
|
||||
if [ "$mask" -eq 64 -a -z "$PREFIXES" -a -n "$EXTENDPREFIX" ]; then
|
||||
proto_add_ipv6_prefix "$addr/$mask,$preferred,$valid"
|
||||
|
||||
local raroutes=""
|
||||
for route in $RA_ROUTES; do
|
||||
local prefix="${route%%/*}"
|
||||
local entry="${route#*/}"
|
||||
local pmask="${entry%%,*}"
|
||||
entry="${entry#*,}"
|
||||
local gw="${entry%%,*}"
|
||||
|
||||
[ -z "$gw" -a "$mask" = "$pmask" ] && {
|
||||
case "$addr" in
|
||||
"${prefix%*::}"*) continue;;
|
||||
esac
|
||||
}
|
||||
raroutes="$raroutes $route"
|
||||
done
|
||||
RA_ROUTES="$raroutes"
|
||||
fi
|
||||
done
|
||||
|
||||
for entry in $RA_ROUTES; do
|
||||
local duplicate=$NOSOURCEFILTER
|
||||
local addr="${entry%%/*}"
|
||||
entry="${entry#*/}"
|
||||
local mask="${entry%%,*}"
|
||||
entry="${entry#*,}"
|
||||
local gw="${entry%%,*}"
|
||||
entry="${entry#*,}"
|
||||
local valid="${entry%%,*}"
|
||||
entry="${entry#*,}"
|
||||
local metric="${entry%%,*}"
|
||||
|
||||
for xentry in $RA_ROUTES; do
|
||||
local xprefix="${xentry%%,*}"
|
||||
xentry="${xentry#*,}"
|
||||
local xgw="${xentry%%,*}"
|
||||
|
||||
[ -n "$gw" -a -z "$xgw" -a "$addr/$mask" = "$xprefix" ] && duplicate=1
|
||||
done
|
||||
|
||||
if [ -z "$gw" -o "$duplicate" = 1 ]; then
|
||||
proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid"
|
||||
else
|
||||
for prefix in $PREFIXES $ADDRESSES; do
|
||||
local paddr="${prefix%%,*}"
|
||||
proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid" "$paddr"
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
proto_add_data
|
||||
[ -n "$CER" ] && json_add_string cer "$CER"
|
||||
[ -n "$PASSTHRU" ] && json_add_string passthru "$PASSTHRU"
|
||||
[ -n "$ZONE" ] && json_add_string zone "$ZONE"
|
||||
proto_close_data
|
||||
|
||||
proto_send_update "$INTERFACE"
|
||||
|
||||
MAPTYPE=""
|
||||
MAPRULE=""
|
||||
|
||||
if [ -n "$MAPE" -a -f /lib/netifd/proto/map.sh ]; then
|
||||
MAPTYPE="map-e"
|
||||
MAPRULE="$MAPE"
|
||||
elif [ -n "$MAPT" -a -f /lib/netifd/proto/map.sh -a -f /proc/net/nat46/control ]; then
|
||||
MAPTYPE="map-t"
|
||||
MAPRULE="$MAPT"
|
||||
elif [ -n "$LW4O6" -a -f /lib/netifd/proto/map.sh ]; then
|
||||
MAPTYPE="lw4o6"
|
||||
MAPRULE="$LW4O6"
|
||||
fi
|
||||
|
||||
[ -n "$ZONE" ] || ZONE=$(fw3 -q network $INTERFACE 2>/dev/null)
|
||||
|
||||
if [ "$IFACE_MAP" != 0 -a -n "$MAPTYPE" -a -n "$MAPRULE" ]; then
|
||||
[ -z "$IFACE_MAP" -o "$IFACE_MAP" = 1 ] && IFACE_MAP=${INTERFACE}_4
|
||||
json_init
|
||||
json_add_string name "$IFACE_MAP"
|
||||
json_add_string ifname "@$INTERFACE"
|
||||
json_add_string proto map
|
||||
json_add_string type "$MAPTYPE"
|
||||
json_add_string _prefsig "$prefsig"
|
||||
[ "$MAPTYPE" = lw4o6 ] && json_add_string _addrsig "$addrsig"
|
||||
json_add_string rule "$MAPRULE"
|
||||
json_add_string tunlink "$INTERFACE"
|
||||
[ -n "$ZONE_MAP" ] || ZONE_MAP=$ZONE
|
||||
[ -n "$ZONE_MAP" ] && json_add_string zone "$ZONE_MAP"
|
||||
[ -n "$ENCAPLIMIT_MAP" ] && json_add_string encaplimit "$ENCAPLIMIT_MAP"
|
||||
[ -n "$IFACE_MAP_DELEGATE" ] && json_add_boolean delegate "$IFACE_MAP_DELEGATE"
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
elif [ -n "$AFTR" -a "$IFACE_DSLITE" != 0 -a -f /lib/netifd/proto/dslite.sh ]; then
|
||||
[ -z "$IFACE_DSLITE" -o "$IFACE_DSLITE" = 1 ] && IFACE_DSLITE=${INTERFACE}_4
|
||||
json_init
|
||||
json_add_string name "$IFACE_DSLITE"
|
||||
json_add_string ifname "@$INTERFACE"
|
||||
json_add_string proto "dslite"
|
||||
json_add_string peeraddr "$AFTR"
|
||||
json_add_string tunlink "$INTERFACE"
|
||||
[ -n "$ZONE_DSLITE" ] || ZONE_DSLITE=$ZONE
|
||||
[ -n "$ZONE_DSLITE" ] && json_add_string zone "$ZONE_DSLITE"
|
||||
[ -n "$ENCAPLIMIT_DSLITE" ] && json_add_string encaplimit "$ENCAPLIMIT_DSLITE"
|
||||
[ -n "$IFACE_DSLITE_DELEGATE" ] && json_add_boolean delegate "$IFACE_DSLITE_DELEGATE"
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
elif [ "$IFACE_464XLAT" != 0 -a -f /lib/netifd/proto/464xlat.sh ]; then
|
||||
[ -z "$IFACE_464XLAT" -o "$IFACE_464XLAT" = 1 ] && IFACE_464XLAT=${INTERFACE}_4
|
||||
json_init
|
||||
json_add_string name "$IFACE_464XLAT"
|
||||
json_add_string ifname "@$INTERFACE"
|
||||
json_add_string proto "464xlat"
|
||||
json_add_string tunlink "$INTERFACE"
|
||||
json_add_string _addrsig "$addrsig"
|
||||
[ -n "$ZONE_464XLAT" ] || ZONE_464XLAT=$ZONE
|
||||
[ -n "$ZONE_464XLAT" ] && json_add_string zone "$ZONE_464XLAT"
|
||||
[ -n "$IFACE_464XLAT_DELEGATE" ] && json_add_boolean delegate "$IFACE_464XLAT_DELEGATE"
|
||||
json_close_object
|
||||
ubus call network add_dynamic "$(json_dump)"
|
||||
fi
|
||||
|
||||
# TODO: $SNTP_IP $SIP_IP $SNTP_FQDN $SIP_DOMAIN
|
||||
}
|
||||
|
||||
teardown_interface() {
|
||||
proto_init_update "*" 0
|
||||
proto_send_update "$INTERFACE"
|
||||
}
|
||||
|
||||
case "$2" in
|
||||
bound)
|
||||
teardown_interface "$1"
|
||||
setup_interface "$1"
|
||||
;;
|
||||
informed|updated|rebound)
|
||||
setup_interface "$1"
|
||||
;;
|
||||
ra-updated)
|
||||
[ -n "$ADDRESSES$RA_ADDRESSES$PREFIXES$USERPREFIX" ] && setup_interface "$1"
|
||||
;;
|
||||
started|stopped|unbound)
|
||||
teardown_interface "$1"
|
||||
;;
|
||||
esac
|
||||
|
||||
# user rules
|
||||
[ -f /etc/odhcp6c.user ] && . /etc/odhcp6c.user "$@"
|
||||
|
||||
exit 0
|
||||
137
package/network/ipv6/odhcp6c/files/dhcpv6.sh
Executable file
137
package/network/ipv6/odhcp6c/files/dhcpv6.sh
Executable file
@@ -0,0 +1,137 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. ../netifd-proto.sh
|
||||
init_proto "$@"
|
||||
|
||||
proto_dhcpv6_init_config() {
|
||||
renew_handler=1
|
||||
|
||||
proto_config_add_string 'reqaddress:or("try","force","none")'
|
||||
proto_config_add_string 'reqprefix:or("auto","no",range(0, 64))'
|
||||
proto_config_add_string clientid
|
||||
proto_config_add_string 'reqopts:list(uinteger)'
|
||||
proto_config_add_string 'defaultreqopts:bool'
|
||||
proto_config_add_string 'noslaaconly:bool'
|
||||
proto_config_add_string 'forceprefix:bool'
|
||||
proto_config_add_string 'extendprefix:bool'
|
||||
proto_config_add_string 'norelease:bool'
|
||||
proto_config_add_string 'noserverunicast:bool'
|
||||
proto_config_add_string 'noclientfqdn:bool'
|
||||
proto_config_add_string 'noacceptreconfig:bool'
|
||||
proto_config_add_array 'ip6prefix:list(ip6addr)'
|
||||
proto_config_add_string iface_dslite
|
||||
proto_config_add_string zone_dslite
|
||||
proto_config_add_string encaplimit_dslite
|
||||
proto_config_add_string iface_map
|
||||
proto_config_add_string zone_map
|
||||
proto_config_add_string encaplimit_map
|
||||
proto_config_add_string iface_464xlat
|
||||
proto_config_add_string zone_464xlat
|
||||
proto_config_add_string zone
|
||||
proto_config_add_string 'ifaceid:ip6addr'
|
||||
proto_config_add_string "userclass"
|
||||
proto_config_add_string "vendorclass"
|
||||
proto_config_add_array "sendopts:list(string)"
|
||||
proto_config_add_boolean delegate
|
||||
proto_config_add_int "soltimeout"
|
||||
proto_config_add_boolean fakeroutes
|
||||
proto_config_add_boolean sourcefilter
|
||||
proto_config_add_boolean keep_ra_dnslifetime
|
||||
proto_config_add_int "ra_holdoff"
|
||||
}
|
||||
|
||||
proto_dhcpv6_add_prefix() {
|
||||
append "$3" "$1"
|
||||
}
|
||||
|
||||
proto_dhcpv6_add_sendopts() {
|
||||
[ -n "$1" ] && append "$3" "-x$1"
|
||||
}
|
||||
|
||||
proto_dhcpv6_setup() {
|
||||
local config="$1"
|
||||
local iface="$2"
|
||||
|
||||
local reqaddress reqprefix clientid reqopts defaultreqopts noslaaconly forceprefix extendprefix norelease noserverunicast noclientfqdn noacceptreconfig ip6prefix ip6prefixes iface_dslite iface_map iface_464xlat ifaceid userclass vendorclass sendopts delegate zone_dslite zone_map zone_464xlat zone encaplimit_dslite encaplimit_map soltimeout fakeroutes sourcefilter keep_ra_dnslifetime ra_holdoff
|
||||
json_get_vars reqaddress reqprefix clientid reqopts defaultreqopts noslaaconly forceprefix extendprefix norelease noserverunicast noclientfqdn noacceptreconfig iface_dslite iface_map iface_464xlat ifaceid userclass vendorclass delegate zone_dslite zone_map zone_464xlat zone encaplimit_dslite encaplimit_map soltimeout fakeroutes sourcefilter keep_ra_dnslifetime ra_holdoff
|
||||
json_for_each_item proto_dhcpv6_add_prefix ip6prefix ip6prefixes
|
||||
|
||||
# Configure
|
||||
local opts=""
|
||||
[ -n "$reqaddress" ] && append opts "-N$reqaddress"
|
||||
|
||||
[ -z "$reqprefix" -o "$reqprefix" = "auto" ] && reqprefix=0
|
||||
[ "$reqprefix" != "no" ] && append opts "-P$reqprefix"
|
||||
|
||||
[ -n "$clientid" ] && append opts "-c$clientid"
|
||||
|
||||
[ "$defaultreqopts" = "0" ] && append opts "-R"
|
||||
|
||||
[ "$noslaaconly" = "1" ] && append opts "-S"
|
||||
|
||||
[ "$forceprefix" = "1" ] && append opts "-F"
|
||||
|
||||
[ "$norelease" = "1" ] && append opts "-k"
|
||||
|
||||
[ "$noserverunicast" = "1" ] && append opts "-U"
|
||||
|
||||
[ "$noclientfqdn" = "1" ] && append opts "-f"
|
||||
|
||||
[ "$noacceptreconfig" = "1" ] && append opts "-a"
|
||||
|
||||
[ -n "$ifaceid" ] && append opts "-i$ifaceid"
|
||||
|
||||
[ -n "$vendorclass" ] && append opts "-V$vendorclass"
|
||||
|
||||
[ -n "$userclass" ] && append opts "-u$userclass"
|
||||
|
||||
[ "$keep_ra_dnslifetime" = "1" ] && append opts "-L"
|
||||
|
||||
[ -n "$ra_holdoff" ] && append opts "-m$ra_holdoff"
|
||||
|
||||
local opt
|
||||
for opt in $reqopts; do
|
||||
append opts "-r$opt"
|
||||
done
|
||||
|
||||
json_for_each_item proto_dhcpv6_add_sendopts sendopts opts
|
||||
|
||||
append opts "-t${soltimeout:-120}"
|
||||
|
||||
[ -n "$ip6prefixes" ] && proto_export "USERPREFIX=$ip6prefixes"
|
||||
[ -n "$iface_dslite" ] && proto_export "IFACE_DSLITE=$iface_dslite"
|
||||
[ -n "$iface_map" ] && proto_export "IFACE_MAP=$iface_map"
|
||||
[ -n "$iface_464xlat" ] && proto_export "IFACE_464XLAT=$iface_464xlat"
|
||||
[ "$delegate" = "0" ] && proto_export "IFACE_DSLITE_DELEGATE=0"
|
||||
[ "$delegate" = "0" ] && proto_export "IFACE_MAP_DELEGATE=0"
|
||||
[ -n "$zone_dslite" ] && proto_export "ZONE_DSLITE=$zone_dslite"
|
||||
[ -n "$zone_map" ] && proto_export "ZONE_MAP=$zone_map"
|
||||
[ -n "$zone_464xlat" ] && proto_export "ZONE_464XLAT=$zone_464xlat"
|
||||
[ -n "$zone" ] && proto_export "ZONE=$zone"
|
||||
[ -n "$encaplimit_dslite" ] && proto_export "ENCAPLIMIT_DSLITE=$encaplimit_dslite"
|
||||
[ -n "$encaplimit_map" ] && proto_export "ENCAPLIMIT_MAP=$encaplimit_map"
|
||||
[ "$fakeroutes" != "0" ] && proto_export "FAKE_ROUTES=1"
|
||||
[ "$sourcefilter" = "0" ] && proto_export "NOSOURCEFILTER=1"
|
||||
[ "$extendprefix" = "1" ] && proto_export "EXTENDPREFIX=1"
|
||||
|
||||
proto_export "INTERFACE=$config"
|
||||
proto_run_command "$config" odhcp6c \
|
||||
-s /lib/netifd/dhcpv6.script \
|
||||
$opts $iface
|
||||
}
|
||||
|
||||
proto_dhcpv6_renew() {
|
||||
local interface="$1"
|
||||
# SIGUSR1 forces odhcp6c to renew its lease
|
||||
local sigusr1="$(kill -l SIGUSR1)"
|
||||
[ -n "$sigusr1" ] && proto_kill_command "$interface" $sigusr1
|
||||
}
|
||||
|
||||
proto_dhcpv6_teardown() {
|
||||
local interface="$1"
|
||||
proto_kill_command "$interface"
|
||||
}
|
||||
|
||||
add_protocol dhcpv6
|
||||
|
||||
61
package/network/ipv6/thc-ipv6/Makefile
Normal file
61
package/network/ipv6/thc-ipv6/Makefile
Normal file
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# Copyright (C) 2009-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=thc-ipv6
|
||||
PKG_VERSION:=2.7
|
||||
PKG_RELEASE:=1
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=http://freeworld.thc.org/releases/
|
||||
PKG_HASH:=440a3ae98b57100c397ec4f8634468dbbb0c3b48788c6b74af2a597a90544a96
|
||||
|
||||
PKG_MAINTAINER:=Jo-Philipp Wich <jo@mein.io>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
THC_APPLETS := \
|
||||
address6 alive6 covert_send6 covert_send6d denial6 detect-new-ip6 \
|
||||
detect_sniffer6 dnsdict6 dnsrevenum6 dos-new-ip6 \
|
||||
dump_router6 exploit6 fake_advertise6 fake_dhcps6 fake_dns6d \
|
||||
fake_dnsupdate6 fake_mipv6 fake_mld26 fake_mld6 fake_mldrouter6 \
|
||||
fake_router26 fake_router6 fake_solicitate6 flood_advertise6 \
|
||||
flood_dhcpc6 flood_mld26 flood_mld6 flood_mldrouter6 flood_router26 \
|
||||
flood_router6 flood_solicitate6 fragmentation6 fuzz_ip6 fuzz_dhcpc6 \
|
||||
fuzz_dhcps6 implementation6 implementation6d inverse_lookup6 \
|
||||
kill_router6 ndpexhaust6 node_query6 parasite6 passive_discovery6 \
|
||||
randicmp6 redir6 rsmurf6 sendpees6 sendpeesmp6 smurf6 thcping6 \
|
||||
toobig6 trace6
|
||||
|
||||
THC_DEPENDS_dnsdict6 := +libpthread
|
||||
THC_DEPENDS_thcping6 := +librt
|
||||
|
||||
define BuildTool
|
||||
define Package/thc-ipv6-$(subst _,-,$(1))
|
||||
TITLE:=THC-IPv6 $(1) utility
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libpcap $(THC_DEPENDS_$(1))
|
||||
URL:=http://freeworld.thc.org/
|
||||
SUBMENU:=THC-IPv6 attack and analyzing toolkit
|
||||
endef
|
||||
|
||||
define Package/thc-ipv6-$(subst _,-,$(1))/description
|
||||
This package contains the $(1) utility of the THC-IPv6 toolkit.
|
||||
endef
|
||||
|
||||
define Package/thc-ipv6-$(subst _,-,$(1))/install
|
||||
$(INSTALL_DIR) $$(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(1) $$(1)/usr/sbin/$(1)
|
||||
endef
|
||||
|
||||
$$(eval $$(call BuildPackage,thc-ipv6-$(subst _,-,$(1))))
|
||||
endef
|
||||
|
||||
$(foreach a,$(THC_APPLETS),$(eval $(call BuildTool,$(a))))
|
||||
@@ -0,0 +1,12 @@
|
||||
diff -urN thc-ipv6-2.7/Makefile thc-ipv6-2.7.new/Makefile
|
||||
--- thc-ipv6-2.7/Makefile 2014-12-27 05:05:30.000000000 -0800
|
||||
+++ thc-ipv6-2.7.new/Makefile 2017-02-04 20:55:51.679898101 -0800
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
CC=gcc
|
||||
#CFLAGS=-g
|
||||
-CFLAGS=-O2
|
||||
+CFLAGS?=-O2
|
||||
CFLAGS+=$(if $(HAVE_SSL),-D_HAVE_SSL,)
|
||||
LDFLAGS+=-lpcap $(if $(HAVE_SSL),-lssl -lcrypto,)
|
||||
PROGRAMS=parasite6 dos-new-ip6 detect-new-ip6 fake_router6 fake_advertise6 fake_solicitate6 fake_mld6 fake_mld26 fake_mldrouter6 flood_mldrouter6 fake_mipv6 redir6 smurf6 alive6 toobig6 rsmurf6 implementation6 implementation6d sendpees6 sendpeesmp6 randicmp6 fuzz_ip6 flood_mld6 flood_mld26 flood_router6 flood_advertise6 flood_solicitate6 trace6 exploit6 denial6 fake_dhcps6 flood_dhcpc6 fake_dns6d fragmentation6 kill_router6 fake_dnsupdate6 ndpexhaust6 detect_sniffer6 dump_router6 fake_router26 flood_router26 passive_discovery6 dnsrevenum6 inverse_lookup6 node_query6 address6 covert_send6 covert_send6d inject_alive6 firewall6 ndpexhaust26 fake_pim6 thcsyn6 redirsniff6 flood_redir6 four2six dump_dhcp6 fuzz_dhcps6 flood_rs6 fuzz_dhcpc6
|
||||
9
package/network/ipv6/thc-ipv6/patches/100-no-ssl.patch
Normal file
9
package/network/ipv6/thc-ipv6/patches/100-no-ssl.patch
Normal file
@@ -0,0 +1,9 @@
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -1,5 +1,5 @@
|
||||
# Comment out if openssl-dev is not present
|
||||
-HAVE_SSL=yes
|
||||
+#HAVE_SSL=yes
|
||||
|
||||
CC=gcc
|
||||
#CFLAGS=-g
|
||||
189
package/network/services/dnsmasq/Makefile
Normal file
189
package/network/services/dnsmasq/Makefile
Normal file
@@ -0,0 +1,189 @@
|
||||
#
|
||||
# Copyright (C) 2006-2016 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dnsmasq
|
||||
PKG_VERSION:=2.80
|
||||
PKG_RELEASE:=1.4
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
|
||||
PKG_HASH:=cdaba2785e92665cf090646cba6f94812760b9d7d8c8d0cfb07ac819377a63bb
|
||||
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
PKG_CPE_ID:=cpe:/a:thekelleys:dnsmasq
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
PKG_INSTALL:=1
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcp \
|
||||
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6 \
|
||||
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec \
|
||||
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth \
|
||||
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset \
|
||||
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_conntrack \
|
||||
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_noid \
|
||||
CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_broken_rtc
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/dnsmasq/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Base system
|
||||
TITLE:=DNS and DHCP server
|
||||
URL:=http://www.thekelleys.org.uk/dnsmasq/
|
||||
DEPENDS:=+libubus
|
||||
USERID:=dnsmasq=453:dnsmasq=453
|
||||
endef
|
||||
|
||||
define Package/dnsmasq
|
||||
$(call Package/dnsmasq/Default)
|
||||
VARIANT:=nodhcpv6
|
||||
endef
|
||||
|
||||
define Package/dnsmasq-dhcpv6
|
||||
$(call Package/dnsmasq/Default)
|
||||
TITLE += (with DHCPv6 support)
|
||||
DEPENDS+=@IPV6
|
||||
VARIANT:=dhcpv6
|
||||
PROVIDES:=dnsmasq
|
||||
endef
|
||||
|
||||
define Package/dnsmasq-full
|
||||
$(call Package/dnsmasq/Default)
|
||||
TITLE += (with DNSSEC, DHCPv6, Auth DNS, IPset, Conntrack, NO_ID enabled by default)
|
||||
DEPENDS+=+PACKAGE_dnsmasq_full_dnssec:libnettle \
|
||||
+PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset \
|
||||
+PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack
|
||||
VARIANT:=full
|
||||
PROVIDES:=dnsmasq
|
||||
endef
|
||||
|
||||
define Package/dnsmasq/description
|
||||
It is intended to provide coupled DNS and DHCP service to a LAN.
|
||||
endef
|
||||
|
||||
define Package/dnsmasq-dhcpv6/description
|
||||
$(call Package/dnsmasq/description)
|
||||
|
||||
This is a variant with DHCPv6 support
|
||||
endef
|
||||
|
||||
define Package/dnsmasq-full/description
|
||||
$(call Package/dnsmasq/description)
|
||||
|
||||
This is a fully configurable variant with DHCPv4, DHCPv6, DNSSEC, Authoritative DNS
|
||||
and IPset, Conntrack support & NO_ID enabled by default.
|
||||
endef
|
||||
|
||||
define Package/dnsmasq/conffiles
|
||||
/etc/config/dhcp
|
||||
/etc/dnsmasq.conf
|
||||
endef
|
||||
|
||||
define Package/dnsmasq-full/config
|
||||
if PACKAGE_dnsmasq-full
|
||||
config PACKAGE_dnsmasq_full_dhcp
|
||||
bool "Build with DHCP support."
|
||||
default y
|
||||
config PACKAGE_dnsmasq_full_dhcpv6
|
||||
bool "Build with DHCPv6 support."
|
||||
depends on IPV6 && PACKAGE_dnsmasq_full_dhcp
|
||||
default y
|
||||
config PACKAGE_dnsmasq_full_dnssec
|
||||
bool "Build with DNSSEC support."
|
||||
default y
|
||||
config PACKAGE_dnsmasq_full_auth
|
||||
bool "Build with the facility to act as an authoritative DNS server."
|
||||
default y
|
||||
config PACKAGE_dnsmasq_full_ipset
|
||||
bool "Build with IPset support."
|
||||
default y
|
||||
config PACKAGE_dnsmasq_full_conntrack
|
||||
bool "Build with Conntrack support."
|
||||
default y
|
||||
config PACKAGE_dnsmasq_full_noid
|
||||
bool "Build with NO_ID. (hide *.bind pseudo domain)"
|
||||
default y
|
||||
config PACKAGE_dnsmasq_full_broken_rtc
|
||||
bool "Build with HAVE_BROKEN_RTC."
|
||||
default n
|
||||
endif
|
||||
endef
|
||||
|
||||
Package/dnsmasq-dhcpv6/conffiles = $(Package/dnsmasq/conffiles)
|
||||
Package/dnsmasq-full/conffiles = $(Package/dnsmasq/conffiles)
|
||||
|
||||
TARGET_CFLAGS += -ffunction-sections -fdata-sections
|
||||
TARGET_LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
COPTS = -DHAVE_UBUS \
|
||||
$(if $(CONFIG_IPV6),,-DNO_IPV6)
|
||||
|
||||
ifeq ($(BUILD_VARIANT),nodhcpv6)
|
||||
COPTS += -DNO_DHCP6
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VARIANT),full)
|
||||
COPTS += $(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcp),,-DNO_DHCP) \
|
||||
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dhcpv6),,-DNO_DHCP6) \
|
||||
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_dnssec),-DHAVE_DNSSEC) \
|
||||
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_auth),,-DNO_AUTH) \
|
||||
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_ipset),,-DNO_IPSET) \
|
||||
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_conntrack),-DHAVE_CONNTRACK,) \
|
||||
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_noid),-DNO_ID,) \
|
||||
$(if $(CONFIG_PACKAGE_dnsmasq_$(BUILD_VARIANT)_broken_rtc),-DHAVE_BROKEN_RTC)
|
||||
COPTS += $(if $(CONFIG_LIBNETTLE_MINI),-DNO_GMP,)
|
||||
else
|
||||
COPTS += -DNO_AUTH -DNO_IPSET -DNO_ID
|
||||
endif
|
||||
|
||||
MAKE_FLAGS := \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS)" \
|
||||
COPTS="$(COPTS)" \
|
||||
PREFIX="/usr"
|
||||
|
||||
define Package/dnsmasq/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/dnsmasq $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DATA) ./files/dhcp.conf $(1)/etc/config/dhcp
|
||||
$(INSTALL_DATA) ./files/dnsmasq.conf $(1)/etc/dnsmasq.conf
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/dhcp
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/neigh
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/ntp
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/tftp
|
||||
$(INSTALL_DATA) ./files/dnsmasqsec.hotplug $(1)/etc/hotplug.d/ntp/25-dnsmasqsec
|
||||
$(INSTALL_DIR) $(1)/usr/share/dnsmasq
|
||||
$(INSTALL_DATA) ./files/dhcpbogushostname.conf $(1)/usr/share/dnsmasq/
|
||||
$(INSTALL_DATA) ./files/rfc6761.conf $(1)/usr/share/dnsmasq/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/dnsmasq
|
||||
$(INSTALL_BIN) ./files/dhcp-script.sh $(1)/usr/lib/dnsmasq/dhcp-script.sh
|
||||
$(INSTALL_DIR) $(1)/usr/share/acl.d
|
||||
$(INSTALL_DATA) ./files/dnsmasq_acl.json $(1)/usr/share/acl.d/
|
||||
endef
|
||||
|
||||
Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)
|
||||
|
||||
define Package/dnsmasq-full/install
|
||||
$(call Package/dnsmasq/install,$(1))
|
||||
ifneq ($(CONFIG_PACKAGE_dnsmasq_full_dnssec),)
|
||||
$(INSTALL_DIR) $(1)/usr/share/dnsmasq
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/trust-anchors.conf $(1)/usr/share/dnsmasq
|
||||
endif
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,dnsmasq))
|
||||
$(eval $(call BuildPackage,dnsmasq-dhcpv6))
|
||||
$(eval $(call BuildPackage,dnsmasq-full))
|
||||
46
package/network/services/dnsmasq/files/dhcp-script.sh
Executable file
46
package/network/services/dnsmasq/files/dhcp-script.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -f "$USER_DHCPSCRIPT" ] && . "$USER_DHCPSCRIPT" "$@"
|
||||
|
||||
case "$1" in
|
||||
add)
|
||||
export ACTION="add"
|
||||
export MACADDR="$2"
|
||||
export IPADDR="$3"
|
||||
export HOSTNAME="$4"
|
||||
exec /sbin/hotplug-call dhcp
|
||||
;;
|
||||
del)
|
||||
export ACTION="remove"
|
||||
export MACADDR="$2"
|
||||
export IPADDR="$3"
|
||||
export HOSTNAME="$4"
|
||||
exec /sbin/hotplug-call dhcp
|
||||
;;
|
||||
old)
|
||||
export ACTION="update"
|
||||
export MACADDR="$2"
|
||||
export IPADDR="$3"
|
||||
export HOSTNAME="$4"
|
||||
exec /sbin/hotplug-call dhcp
|
||||
;;
|
||||
arp-add)
|
||||
export ACTION="add"
|
||||
export MACADDR="$2"
|
||||
export IPADDR="$3"
|
||||
exec /sbin/hotplug-call neigh
|
||||
;;
|
||||
arp-del)
|
||||
export ACTION="remove"
|
||||
export MACADDR="$2"
|
||||
export IPADDR="$3"
|
||||
exec /sbin/hotplug-call neigh
|
||||
;;
|
||||
tftp)
|
||||
export ACTION="add"
|
||||
export TFTP_SIZE="$2"
|
||||
export TFTP_ADDR="$3"
|
||||
export TFTP_PATH="$4"
|
||||
exec /sbin/hotplug-call tftp
|
||||
;;
|
||||
esac
|
||||
32
package/network/services/dnsmasq/files/dhcp.conf
Normal file
32
package/network/services/dnsmasq/files/dhcp.conf
Normal file
@@ -0,0 +1,32 @@
|
||||
config dnsmasq
|
||||
option domainneeded 1
|
||||
option boguspriv 1
|
||||
option filterwin2k 0 # enable for dial on demand
|
||||
option localise_queries 1
|
||||
option rebind_protection 1 # disable if upstream must serve RFC1918 addresses
|
||||
option rebind_localhost 1 # enable for RBL checking and similar services
|
||||
#list rebind_domain example.lan # whitelist RFC1918 responses for domains
|
||||
option local '/lan/'
|
||||
option domain 'lan'
|
||||
option expandhosts 1
|
||||
option nonegcache 0
|
||||
option authoritative 1
|
||||
option readethers 1
|
||||
option leasefile '/tmp/dhcp.leases'
|
||||
option resolvfile '/tmp/resolv.conf.auto'
|
||||
#list server '/mycompany.local/1.2.3.4'
|
||||
option nonwildcard 1 # bind to & keep track of interfaces
|
||||
#list interface br-lan
|
||||
#list notinterface lo
|
||||
#list bogusnxdomain '64.94.110.11'
|
||||
option localservice 1 # disable to allow DNS requests from non-local subnets
|
||||
|
||||
config dhcp lan
|
||||
option interface lan
|
||||
option start 100
|
||||
option limit 150
|
||||
option leasetime 12h
|
||||
|
||||
config dhcp wan
|
||||
option interface wan
|
||||
option ignore 1
|
||||
@@ -0,0 +1,8 @@
|
||||
# dhcpbogushostname.conf included configuration file for dnsmasq
|
||||
#
|
||||
# includes a list of hostnames that should not be associated with dhcp leases
|
||||
# in response to CERT VU#598349
|
||||
# file included by default, option dhcpbogushostname 0 to disable
|
||||
|
||||
dhcp-name-match=set:dhcp_bogus_hostname,localhost
|
||||
dhcp-name-match=set:dhcp_bogus_hostname,wpad
|
||||
37
package/network/services/dnsmasq/files/dnsmasq.conf
Normal file
37
package/network/services/dnsmasq/files/dnsmasq.conf
Normal file
@@ -0,0 +1,37 @@
|
||||
# Change the following lines if you want dnsmasq to serve SRV
|
||||
# records.
|
||||
# You may add multiple srv-host lines.
|
||||
# The fields are <name>,<target>,<port>,<priority>,<weight>
|
||||
|
||||
# A SRV record sending LDAP for the example.com domain to
|
||||
# ldapserver.example.com port 289
|
||||
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
|
||||
|
||||
# Two SRV records for LDAP, each with different priorities
|
||||
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
|
||||
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
|
||||
|
||||
# A SRV record indicating that there is no LDAP server for the domain
|
||||
# example.com
|
||||
#srv-host=_ldap._tcp.example.com
|
||||
|
||||
# The following line shows how to make dnsmasq serve an arbitrary PTR
|
||||
# record. This is useful for DNS-SD.
|
||||
# The fields are <name>,<target>
|
||||
#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
|
||||
|
||||
# Change the following lines to enable dnsmasq to serve TXT records.
|
||||
# These are used for things like SPF and zeroconf.
|
||||
# The fields are <name>,<text>,<text>...
|
||||
|
||||
#Example SPF.
|
||||
#txt-record=example.com,"v=spf1 a -all"
|
||||
|
||||
#Example zeroconf
|
||||
#txt-record=_http._tcp.example.com,name=value,paper=A4
|
||||
|
||||
# Provide an alias for a "local" DNS name. Note that this _only_ works
|
||||
# for targets which are names from DHCP or /etc/hosts. Give host
|
||||
# "bert" another name, bertrand
|
||||
# The fields are <cname>,<target>
|
||||
#cname=bertand,bert
|
||||
1132
package/network/services/dnsmasq/files/dnsmasq.init
Normal file
1132
package/network/services/dnsmasq/files/dnsmasq.init
Normal file
File diff suppressed because it is too large
Load Diff
4
package/network/services/dnsmasq/files/dnsmasq_acl.json
Normal file
4
package/network/services/dnsmasq/files/dnsmasq_acl.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"user": "dnsmasq",
|
||||
"publish": [ "dnsmasq" ]
|
||||
}
|
||||
14
package/network/services/dnsmasq/files/dnsmasqsec.hotplug
Normal file
14
package/network/services/dnsmasq/files/dnsmasqsec.hotplug
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions/procd.sh
|
||||
|
||||
TIMEVALIDFILE="/var/state/dnsmasqsec"
|
||||
|
||||
[ "$ACTION" = stratum ] || exit 0
|
||||
|
||||
[ -f "$TIMEVALIDFILE" ] || {
|
||||
echo "ntpd says time is valid" >$TIMEVALIDFILE
|
||||
/etc/init.d/dnsmasq enabled && {
|
||||
procd_send_signal dnsmasq '*' INT
|
||||
}
|
||||
}
|
||||
11
package/network/services/dnsmasq/files/rfc6761.conf
Normal file
11
package/network/services/dnsmasq/files/rfc6761.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
# RFC6761 included configuration file for dnsmasq
|
||||
#
|
||||
# includes a list of domains that should not be forwarded to Internet name servers
|
||||
# to reduce burden on them, asking questions that they won't know the answer to.
|
||||
|
||||
server=/bind/
|
||||
server=/invalid/
|
||||
server=/local/
|
||||
server=/localhost/
|
||||
server=/onion/
|
||||
server=/test/
|
||||
@@ -0,0 +1,57 @@
|
||||
From 18eac67c0a15b673c8d27002c248651b308093e4 Mon Sep 17 00:00:00 2001
|
||||
From: Steven Siloti <ssiloti@gmail.com>
|
||||
Date: Sun, 13 Jan 2019 22:56:36 +0000
|
||||
Subject: [PATCH 30/30] Fix entries in /etc/hosts disabling static leases.
|
||||
|
||||
It is possible for a config entry to have one address family specified by a
|
||||
dhcp-host directive and the other added from /etc/hosts. This is especially
|
||||
common on OpenWrt because it uses odhcpd for DHCPv6 and IPv6 leases are
|
||||
imported into dnsmasq via a hosts file.
|
||||
|
||||
To handle this case there need to be separate *_HOSTS flags for IPv4 and IPv6.
|
||||
Otherwise when the hosts file is reloaded it will clear the CONFIG_ADDR(6) flag
|
||||
which was set by the dhcp-host directive.
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
|
||||
---
|
||||
src/dhcp-common.c | 8 ++++++--
|
||||
src/dnsmasq.h | 1 +
|
||||
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/dhcp-common.c
|
||||
+++ b/src/dhcp-common.c
|
||||
@@ -371,8 +371,14 @@ void dhcp_update_configs(struct dhcp_con
|
||||
int prot = AF_INET;
|
||||
|
||||
for (config = configs; config; config = config->next)
|
||||
+ {
|
||||
if (config->flags & CONFIG_ADDR_HOSTS)
|
||||
- config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR6 | CONFIG_ADDR_HOSTS);
|
||||
+ config->flags &= ~(CONFIG_ADDR | CONFIG_ADDR_HOSTS);
|
||||
+#ifdef HAVE_DHCP6
|
||||
+ if (config->flags & CONFIG_ADDR6_HOSTS)
|
||||
+ config->flags &= ~(CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS);
|
||||
+#endif
|
||||
+ }
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
again:
|
||||
@@ -421,7 +427,7 @@ void dhcp_update_configs(struct dhcp_con
|
||||
(!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 128, 0)) || conf_tmp == config))
|
||||
{
|
||||
memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ);
|
||||
- config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS;
|
||||
+ config->flags |= CONFIG_ADDR6 | CONFIG_ADDR6_HOSTS;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -796,6 +796,7 @@ struct dhcp_config {
|
||||
#define CONFIG_BANK 2048 /* from dhcp hosts file */
|
||||
#define CONFIG_ADDR6 4096
|
||||
#define CONFIG_WILDCARD 8192
|
||||
+#define CONFIG_ADDR6_HOSTS 16384 /* address added by from /etc/hosts */
|
||||
|
||||
struct dhcp_opt {
|
||||
int opt, len, flags;
|
||||
@@ -0,0 +1,65 @@
|
||||
--- a/src/ipset.c
|
||||
+++ b/src/ipset.c
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
-#include <sys/utsname.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/netlink.h>
|
||||
@@ -72,7 +71,7 @@ struct my_nfgenmsg {
|
||||
|
||||
#define NL_ALIGN(len) (((len)+3) & ~(3))
|
||||
static const struct sockaddr_nl snl = { .nl_family = AF_NETLINK };
|
||||
-static int ipset_sock, old_kernel;
|
||||
+static int ipset_sock;
|
||||
static char *buffer;
|
||||
|
||||
static inline void add_attr(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
|
||||
@@ -87,25 +86,7 @@ static inline void add_attr(struct nlmsg
|
||||
|
||||
void ipset_init(void)
|
||||
{
|
||||
- struct utsname utsname;
|
||||
- int version;
|
||||
- char *split;
|
||||
-
|
||||
- if (uname(&utsname) < 0)
|
||||
- die(_("failed to find kernel version: %s"), NULL, EC_MISC);
|
||||
-
|
||||
- split = strtok(utsname.release, ".");
|
||||
- version = (split ? atoi(split) : 0);
|
||||
- split = strtok(NULL, ".");
|
||||
- version = version * 256 + (split ? atoi(split) : 0);
|
||||
- split = strtok(NULL, ".");
|
||||
- version = version * 256 + (split ? atoi(split) : 0);
|
||||
- old_kernel = (version < KERNEL_VERSION(2,6,32));
|
||||
-
|
||||
- if (old_kernel && (ipset_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1)
|
||||
- return;
|
||||
-
|
||||
- if (!old_kernel &&
|
||||
+ if (
|
||||
(buffer = safe_malloc(BUFF_SZ)) &&
|
||||
(ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 &&
|
||||
(bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1))
|
||||
@@ -217,17 +198,10 @@ int add_to_ipset(const char *setname, co
|
||||
if (flags & F_IPV6)
|
||||
{
|
||||
af = AF_INET6;
|
||||
- /* old method only supports IPv4 */
|
||||
- if (old_kernel)
|
||||
- {
|
||||
- errno = EAFNOSUPPORT ;
|
||||
- ret = -1;
|
||||
- }
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (ret != -1)
|
||||
- ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
+ ret = new_add_to_ipset(setname, ipaddr, af, remove);
|
||||
|
||||
if (ret == -1)
|
||||
my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno));
|
||||
@@ -0,0 +1,47 @@
|
||||
From 79e60e145f8a595bca5a784c00b437216d51de68 Mon Sep 17 00:00:00 2001
|
||||
From: Steven Barth <steven@midlink.org>
|
||||
Date: Mon, 13 Apr 2015 09:45:20 +0200
|
||||
Subject: [PATCH] dnssec: improve timestamp heuristic
|
||||
|
||||
Signed-off-by: Steven Barth <steven@midlink.org>
|
||||
---
|
||||
src/dnssec.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -143,17 +143,24 @@ static time_t timestamp_time;
|
||||
int setup_timestamp(void)
|
||||
{
|
||||
struct stat statbuf;
|
||||
+ time_t now;
|
||||
+ time_t base = 1420070400; /* 1-1-2015 */
|
||||
|
||||
daemon->back_to_the_future = 0;
|
||||
|
||||
if (!daemon->timestamp_file)
|
||||
return 0;
|
||||
+
|
||||
+ now = time(NULL);
|
||||
+
|
||||
+ if (!stat("/proc/self/exe", &statbuf) && difftime(statbuf.st_mtime, base) > 0)
|
||||
+ base = statbuf.st_mtime;
|
||||
|
||||
if (stat(daemon->timestamp_file, &statbuf) != -1)
|
||||
{
|
||||
timestamp_time = statbuf.st_mtime;
|
||||
check_and_exit:
|
||||
- if (difftime(timestamp_time, time(0)) <= 0)
|
||||
+ if (difftime(now, base) >= 0 && difftime(timestamp_time, now) <= 0)
|
||||
{
|
||||
/* time already OK, update timestamp, and do key checking from the start. */
|
||||
if (utimes(daemon->timestamp_file, NULL) == -1)
|
||||
@@ -174,7 +181,7 @@ int setup_timestamp(void)
|
||||
|
||||
close(fd);
|
||||
|
||||
- timestamp_time = 1420070400; /* 1-1-2015 */
|
||||
+ timestamp_time = base; /* 1-1-2015 */
|
||||
tv[0].tv_sec = tv[1].tv_sec = timestamp_time;
|
||||
tv[0].tv_usec = tv[1].tv_usec = 0;
|
||||
if (utimes(daemon->timestamp_file, tv) == 0)
|
||||
@@ -0,0 +1,18 @@
|
||||
dnsmasq: fix warning with poll.h include on musl
|
||||
|
||||
Warning is:
|
||||
#warning redirecting incorrect #include <sys/poll.h> to <poll.h>
|
||||
|
||||
Signed-off-by: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
|
||||
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -95,7 +95,7 @@ typedef unsigned long long u64;
|
||||
#if defined(HAVE_SOLARIS_NETWORK)
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
-#include <sys/poll.h>
|
||||
+#include <poll.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/un.h>
|
||||
59
package/network/services/dropbear/Config.in
Normal file
59
package/network/services/dropbear/Config.in
Normal file
@@ -0,0 +1,59 @@
|
||||
menu "Configuration"
|
||||
depends on PACKAGE_dropbear
|
||||
|
||||
config DROPBEAR_CURVE25519
|
||||
bool "Curve25519 support"
|
||||
default y
|
||||
help
|
||||
This enables the following key exchange algorithm:
|
||||
curve25519-sha256@libssh.org
|
||||
|
||||
Increases binary size by about 13 kB uncompressed (MIPS).
|
||||
|
||||
config DROPBEAR_ECC
|
||||
bool "Elliptic curve cryptography (ECC)"
|
||||
default n
|
||||
help
|
||||
Enables elliptic curve cryptography (ECC) support in key exchange and public key
|
||||
authentication.
|
||||
|
||||
Key exchange algorithms:
|
||||
ecdh-sha2-nistp256
|
||||
ecdh-sha2-nistp384
|
||||
ecdh-sha2-nistp521
|
||||
|
||||
Public key algorithms:
|
||||
ecdsa-sha2-nistp256
|
||||
ecdsa-sha2-nistp384
|
||||
ecdsa-sha2-nistp521
|
||||
|
||||
Does not generate ECC host keys by default (ECC key exchange will not be used,
|
||||
only ECC public key auth).
|
||||
|
||||
Increases binary size by about 23 kB (MIPS).
|
||||
|
||||
config DROPBEAR_ZLIB
|
||||
bool "Enable compression"
|
||||
default n
|
||||
help
|
||||
Enables compression using shared zlib library.
|
||||
|
||||
Increases binary size by about 0.1 kB (MIPS) and requires additional 62 kB (MIPS)
|
||||
for a shared zlib library.
|
||||
|
||||
config DROPBEAR_UTMP
|
||||
bool "Utmp support"
|
||||
default n
|
||||
depends on BUSYBOX_CONFIG_FEATURE_UTMP
|
||||
help
|
||||
This enables dropbear utmp support, the file /var/run/utmp is used to
|
||||
track who is currently logged in.
|
||||
|
||||
config DROPBEAR_PUTUTLINE
|
||||
bool "Pututline support"
|
||||
default n
|
||||
depends on DROPBEAR_UTMP
|
||||
help
|
||||
Dropbear will use pututline() to write the utmp structure into the utmp file.
|
||||
|
||||
endmenu
|
||||
155
package/network/services/dropbear/Makefile
Normal file
155
package/network/services/dropbear/Makefile
Normal file
@@ -0,0 +1,155 @@
|
||||
#
|
||||
# Copyright (C) 2006-2016 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dropbear
|
||||
PKG_VERSION:=2017.75
|
||||
PKG_RELEASE:=7.1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:= \
|
||||
http://matt.ucc.asn.au/dropbear/releases/ \
|
||||
https://dropbear.nl/mirror/releases/
|
||||
PKG_HASH:=6cbc1dcb1c9709d226dff669e5604172a18cf5dbf9a201474d5618ae4465098c
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE libtomcrypt/LICENSE libtommath/LICENSE
|
||||
PKG_CPE_ID:=cpe:/a:matt_johnston:dropbear_ssh_server
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_TARGET_INIT_PATH CONFIG_DROPBEAR_ECC \
|
||||
CONFIG_DROPBEAR_CURVE25519 CONFIG_DROPBEAR_ZLIB \
|
||||
CONFIG_DROPBEAR_UTMP CONFIG_DROPBEAR_PUTUTLINE
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
ifneq ($(DUMP),1)
|
||||
STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell echo $(CONFIG_TARGET_INIT_PATH) | mkhash md5)
|
||||
endif
|
||||
|
||||
define Package/dropbear/Default
|
||||
URL:=http://matt.ucc.asn.au/dropbear/
|
||||
endef
|
||||
|
||||
define Package/dropbear/config
|
||||
source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
define Package/dropbear
|
||||
$(call Package/dropbear/Default)
|
||||
SECTION:=net
|
||||
CATEGORY:=Base system
|
||||
TITLE:=Small SSH2 client/server
|
||||
DEPENDS:= +DROPBEAR_ZLIB:zlib
|
||||
ALTERNATIVES:=\
|
||||
100:/usr/bin/ssh:/usr/sbin/dropbear \
|
||||
100:/usr/bin/scp:/usr/sbin/dropbear \
|
||||
|
||||
endef
|
||||
|
||||
define Package/dropbear/description
|
||||
A small SSH2 server/client designed for small memory environments.
|
||||
endef
|
||||
|
||||
define Package/dropbear/conffiles
|
||||
/etc/dropbear/dropbear_rsa_host_key
|
||||
/etc/config/dropbear
|
||||
endef
|
||||
|
||||
define Package/dropbearconvert
|
||||
$(call Package/dropbear/Default)
|
||||
SECTION:=utils
|
||||
CATEGORY:=Utilities
|
||||
TITLE:=Utility for converting SSH keys
|
||||
endef
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--disable-pam \
|
||||
--enable-openpty \
|
||||
--enable-syslog \
|
||||
--disable-lastlog \
|
||||
--disable-utmpx \
|
||||
$(if $(CONFIG_DROPBEAR_UTMP),,--disable-utmp) \
|
||||
--disable-wtmp \
|
||||
--disable-wtmpx \
|
||||
--disable-loginfunc \
|
||||
$(if $(CONFIG_DROPBEAR_PUTUTLINE),,--disable-pututline) \
|
||||
--disable-pututxline \
|
||||
$(if $(CONFIG_DROPBEAR_ZLIB),,--disable-zlib) \
|
||||
--enable-bundled-libtom
|
||||
|
||||
TARGET_CFLAGS += -DARGTYPE=3 -ffunction-sections -fdata-sections
|
||||
TARGET_LDFLAGS += -Wl,--gc-sections
|
||||
|
||||
define Build/Configure
|
||||
$(Build/Configure/Default)
|
||||
|
||||
$(SED) 's,^#define DEFAULT_PATH .*$$$$,#define DEFAULT_PATH "$(TARGET_INIT_PATH)",g' \
|
||||
$(PKG_BUILD_DIR)/options.h
|
||||
|
||||
awk 'BEGIN { rc = 1 } \
|
||||
/'DROPBEAR_CURVE25519'/ { $$$$0 = "$(if $(CONFIG_DROPBEAR_CURVE25519),,// )#define 'DROPBEAR_CURVE25519'"; rc = 0 } \
|
||||
{ print } \
|
||||
END { exit(rc) }' $(PKG_BUILD_DIR)/options.h \
|
||||
>$(PKG_BUILD_DIR)/options.h.new && \
|
||||
mv $(PKG_BUILD_DIR)/options.h.new $(PKG_BUILD_DIR)/options.h
|
||||
|
||||
# Enforce that all replacements are made, otherwise options.h has changed
|
||||
# format and this logic is broken.
|
||||
for OPTION in DROPBEAR_ECDSA DROPBEAR_ECDH; do \
|
||||
awk 'BEGIN { rc = 1 } \
|
||||
/'$$$$OPTION'/ { $$$$0 = "$(if $(CONFIG_DROPBEAR_ECC),,// )#define '$$$$OPTION'"; rc = 0 } \
|
||||
{ print } \
|
||||
END { exit(rc) }' $(PKG_BUILD_DIR)/options.h \
|
||||
>$(PKG_BUILD_DIR)/options.h.new && \
|
||||
mv $(PKG_BUILD_DIR)/options.h.new $(PKG_BUILD_DIR)/options.h || exit 1; \
|
||||
done
|
||||
|
||||
# remove protocol idented software version number
|
||||
$(SED) 's,^#define LOCAL_IDENT .*$$$$,#define LOCAL_IDENT "SSH-2.0-dropbear",g' \
|
||||
$(PKG_BUILD_DIR)/sysoptions.h
|
||||
|
||||
# Enforce rebuild of svr-chansession.c
|
||||
rm -f $(PKG_BUILD_DIR)/svr-chansession.o
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
PROGRAMS="dropbear dbclient dropbearkey scp" \
|
||||
MULTI=1 SCPPROGRESS=1
|
||||
+$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
PROGRAMS="dropbearconvert"
|
||||
endef
|
||||
|
||||
define Package/dropbear/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dropbearmulti $(1)/usr/sbin/dropbear
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(LN) ../sbin/dropbear $(1)/usr/bin/dbclient
|
||||
$(LN) ../sbin/dropbear $(1)/usr/bin/dropbearkey
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DATA) ./files/dropbear.config $(1)/etc/config/dropbear
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/dropbear.init $(1)/etc/init.d/dropbear
|
||||
$(INSTALL_DIR) $(1)/usr/lib/opkg/info
|
||||
$(INSTALL_DIR) $(1)/etc/dropbear
|
||||
touch $(1)/etc/dropbear/dropbear_rsa_host_key
|
||||
endef
|
||||
|
||||
define Package/dropbearconvert/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/dropbearconvert $(1)/usr/bin/dropbearconvert
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,dropbear))
|
||||
$(eval $(call BuildPackage,dropbearconvert))
|
||||
5
package/network/services/dropbear/files/dropbear.config
Normal file
5
package/network/services/dropbear/files/dropbear.config
Normal file
@@ -0,0 +1,5 @@
|
||||
config dropbear
|
||||
option PasswordAuth 'on'
|
||||
option RootPasswordAuth 'on'
|
||||
option Port '22'
|
||||
# option BannerFile '/etc/banner'
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user