diff options
Diffstat (limited to 'package/network/config')
182 files changed, 14139 insertions, 0 deletions
diff --git a/package/network/config/.svn/entries b/package/network/config/.svn/entries new file mode 100644 index 0000000..d67b0a3 --- /dev/null +++ b/package/network/config/.svn/entries @@ -0,0 +1,49 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config +svn://svn.openwrt.org/openwrt + + + +2013-03-14T15:29:43.028686Z +36009 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +swconfig +dir + +firewall +dir + +qos-scripts +dir + +soloscli +dir + +firewall3 +dir + +netifd +dir + +ltq-dsl-app +dir + diff --git a/package/network/config/firewall/.svn/entries b/package/network/config/firewall/.svn/entries new file mode 100644 index 0000000..71ff12e --- /dev/null +++ b/package/network/config/firewall/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/firewall +svn://svn.openwrt.org/openwrt + + + +2013-02-22T13:45:20.660376Z +35745 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +Makefile +file + + + + +2013-03-17T12:13:19.000000Z +9c007669af2d2b8ab109dc5c431df790 +2013-02-22T13:45:20.660376Z +35745 +jow + + + + + + + + + + + + + + + + + + + + + +1568 + diff --git a/package/network/config/firewall/.svn/text-base/Makefile.svn-base b/package/network/config/firewall/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..998b274 --- /dev/null +++ b/package/network/config/firewall/.svn/text-base/Makefile.svn-base @@ -0,0 +1,58 @@ +# +# Copyright (C) 2008-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:=firewall + +PKG_VERSION:=2 +PKG_RELEASE:=59 + +include $(INCLUDE_DIR)/package.mk + +define Package/firewall + SECTION:=net + CATEGORY:=Base system + URL:=http://openwrt.org/ + TITLE:=OpenWrt firewall + MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org> + DEPENDS:=+iptables +kmod-ipt-conntrack +kmod-ipt-nat + PKGARCH:=all +endef + +define Package/firewall/description + UCI based firewall for OpenWrt +endef + +define Build/Compile + true +endef + +define Package/firewall/conffiles +/etc/config/firewall +/etc/firewall.user +endef + +define Package/firewall/install + $(INSTALL_DIR) $(1)/lib/firewall + $(INSTALL_DATA) ./files/lib/*.sh $(1)/lib/firewall + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) ./files/bin/fw $(1)/sbin + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/firewall.config $(1)/etc/config/firewall + $(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/hotplug.d/firewall + $(INSTALL_DATA) ./files/reflection.hotplug $(1)/etc/hotplug.d/firewall/10-nat-reflection + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) ./files/firewall.user $(1)/etc + $(INSTALL_DIR) $(1)/lib/upgrade/keep.d + $(INSTALL_DATA) ./files/firewall.upgrade $(1)/lib/upgrade/keep.d/firewall +endef + +$(eval $(call BuildPackage,firewall)) diff --git a/package/network/config/firewall/Makefile b/package/network/config/firewall/Makefile new file mode 100644 index 0000000..998b274 --- /dev/null +++ b/package/network/config/firewall/Makefile @@ -0,0 +1,58 @@ +# +# Copyright (C) 2008-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:=firewall + +PKG_VERSION:=2 +PKG_RELEASE:=59 + +include $(INCLUDE_DIR)/package.mk + +define Package/firewall + SECTION:=net + CATEGORY:=Base system + URL:=http://openwrt.org/ + TITLE:=OpenWrt firewall + MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org> + DEPENDS:=+iptables +kmod-ipt-conntrack +kmod-ipt-nat + PKGARCH:=all +endef + +define Package/firewall/description + UCI based firewall for OpenWrt +endef + +define Build/Compile + true +endef + +define Package/firewall/conffiles +/etc/config/firewall +/etc/firewall.user +endef + +define Package/firewall/install + $(INSTALL_DIR) $(1)/lib/firewall + $(INSTALL_DATA) ./files/lib/*.sh $(1)/lib/firewall + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) ./files/bin/fw $(1)/sbin + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_DATA) ./files/firewall.config $(1)/etc/config/firewall + $(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/hotplug.d/firewall + $(INSTALL_DATA) ./files/reflection.hotplug $(1)/etc/hotplug.d/firewall/10-nat-reflection + $(INSTALL_DIR) $(1)/etc + $(INSTALL_DATA) ./files/firewall.user $(1)/etc + $(INSTALL_DIR) $(1)/lib/upgrade/keep.d + $(INSTALL_DATA) ./files/firewall.upgrade $(1)/lib/upgrade/keep.d/firewall +endef + +$(eval $(call BuildPackage,firewall)) diff --git a/package/network/config/firewall/files/.svn/entries b/package/network/config/firewall/files/.svn/entries new file mode 100644 index 0000000..a284479 --- /dev/null +++ b/package/network/config/firewall/files/.svn/entries @@ -0,0 +1,238 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/firewall/files +svn://svn.openwrt.org/openwrt + + + +2013-02-22T13:45:20.660376Z +35745 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +firewall.user +file + + + + +2013-03-17T12:13:19.000000Z +43e25ef73306f7ea73813d648990b181 +2009-04-12T22:38:34.928337Z +15221 +jow + + + + + + + + + + + + + + + + + + + + + +139 + +lib +dir + +firewall.hotplug +file + + + + +2013-03-17T12:13:19.000000Z +3e4ca650dcd8df46170f1bd1957af5e2 +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + + + + + + + + +537 + +firewall.init +file + + + + +2013-03-17T12:13:19.000000Z +b16182f0af632fe00a9a703f7e18acb1 +2010-05-19T00:50:14.834146Z +21502 +jow +has-props + + + + + + + + + + + + + + + + + + + + +233 + +bin +dir + +firewall.config +file + + + + +2013-03-17T12:13:19.000000Z +f952253dc6cb85d189857c3fead88362 +2013-01-04T15:59:28.919139Z +35012 +cyrus +has-props + + + + + + + + + + + + + + + + + + + + +4244 + +firewall.upgrade +file + + + + +2013-03-17T12:13:19.000000Z +701504dad753d669d9667c04214bd28c +2011-03-20T00:57:47.962557Z +26241 +thepeople + + + + + + + + + + + + + + + + + + + + + +19 + +reflection.hotplug +file + + + + +2013-03-17T12:13:19.000000Z +0f2936ae3cb153db2a8a85a395d7257f +2012-12-07T13:08:28.401778Z +34569 +jow + + + + + + + + + + + + + + + + + + + + + +3935 + diff --git a/package/network/config/firewall/files/.svn/prop-base/firewall.config.svn-base b/package/network/config/firewall/files/.svn/prop-base/firewall.config.svn-base new file mode 100644 index 0000000..3160658 --- /dev/null +++ b/package/network/config/firewall/files/.svn/prop-base/firewall.config.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mergeinfo +V 0 + +END diff --git a/package/network/config/firewall/files/.svn/prop-base/firewall.init.svn-base b/package/network/config/firewall/files/.svn/prop-base/firewall.init.svn-base new file mode 100644 index 0000000..8d28d86 --- /dev/null +++ b/package/network/config/firewall/files/.svn/prop-base/firewall.init.svn-base @@ -0,0 +1,9 @@ +K 14 +svn:executable +V 1 +* +K 13 +svn:mergeinfo +V 0 + +END diff --git a/package/network/config/firewall/files/.svn/text-base/firewall.config.svn-base b/package/network/config/firewall/files/.svn/text-base/firewall.config.svn-base new file mode 100644 index 0000000..6acfe1e --- /dev/null +++ b/package/network/config/firewall/files/.svn/text-base/firewall.config.svn-base @@ -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 + option network 'lan' + option input ACCEPT + option output ACCEPT + option forward REJECT + +config zone + option name wan + option network 'wan' + 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 + +# 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 fe80::/10 + option src_port 547 + option dest_ip fe80::/10 + option dest_port 546 + 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 + +# Block ULA-traffic from leaking out +config rule + option name Enforce-ULA-Border-Src + option src * + option dest wan + option proto all + option src_ip fc00::/7 + option family ipv6 + option target REJECT + +config rule + option name Enforce-ULA-Border-Dest + option src * + option dest wan + option proto all + option dest_ip fc00::/7 + option family ipv6 + option target REJECT + +# 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 + +# allow IPsec/ESP and ISAKMP passthrough +#config rule +# option src wan +# option dest lan +# option protocol esp +# option target ACCEPT + +#config rule +# option src wan +# option dest lan +# option src_port 500 +# option dest_port 500 +# option proto udp +# option target ACCEPT + +### 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 diff --git a/package/network/config/firewall/files/.svn/text-base/firewall.hotplug.svn-base b/package/network/config/firewall/files/.svn/text-base/firewall.hotplug.svn-base new file mode 100644 index 0000000..52e7798 --- /dev/null +++ b/package/network/config/firewall/files/.svn/text-base/firewall.hotplug.svn-base @@ -0,0 +1,22 @@ +#!/bin/sh +# This script is executed as part of the hotplug event with +# HOTPLUG_TYPE=iface, triggered by various scripts when an interface +# is configured (ACTION=ifup) or deconfigured (ACTION=ifdown). The +# interface is available as INTERFACE, the real device as DEVICE. + +[ "$DEVICE" == "lo" ] && exit 0 + +. /lib/functions.sh +. /lib/firewall/core.sh + +fw_init +fw_is_loaded || exit 0 + +case "$ACTION" in + ifup) + fw_configure_interface "$INTERFACE" add "$DEVICE" & + ;; + ifdown) + fw_configure_interface "$INTERFACE" del "$DEVICE" + ;; +esac diff --git a/package/network/config/firewall/files/.svn/text-base/firewall.init.svn-base b/package/network/config/firewall/files/.svn/text-base/firewall.init.svn-base new file mode 100644 index 0000000..a2fd0a0 --- /dev/null +++ b/package/network/config/firewall/files/.svn/text-base/firewall.init.svn-base @@ -0,0 +1,27 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008-2010 OpenWrt.org + +START=45 + +FW_LIBDIR=/lib/firewall + +fw() { + . $FW_LIBDIR/core.sh + fw_$1 +} + +start() { + fw start +} + +stop() { + fw stop +} + +restart() { + fw restart +} + +reload() { + fw reload +} diff --git a/package/network/config/firewall/files/.svn/text-base/firewall.upgrade.svn-base b/package/network/config/firewall/files/.svn/text-base/firewall.upgrade.svn-base new file mode 100644 index 0000000..64f63eb --- /dev/null +++ b/package/network/config/firewall/files/.svn/text-base/firewall.upgrade.svn-base @@ -0,0 +1 @@ +/etc/firewall.user diff --git a/package/network/config/firewall/files/.svn/text-base/firewall.user.svn-base b/package/network/config/firewall/files/.svn/text-base/firewall.user.svn-base new file mode 100644 index 0000000..1ccbd01 --- /dev/null +++ b/package/network/config/firewall/files/.svn/text-base/firewall.user.svn-base @@ -0,0 +1,4 @@ +# This file is interpreted as shell script. +# Put your custom iptables rules here, they will +# be executed with each firewall (re-)start. + diff --git a/package/network/config/firewall/files/.svn/text-base/reflection.hotplug.svn-base b/package/network/config/firewall/files/.svn/text-base/reflection.hotplug.svn-base new file mode 100644 index 0000000..129a922 --- /dev/null +++ b/package/network/config/firewall/files/.svn/text-base/reflection.hotplug.svn-base @@ -0,0 +1,169 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh + +if [ "$ACTION" = "remove" ]; then + + delete_rules_by_comment() { + local table="$1" + local chain="$2" + local comment="$3" + + iptables -t "$table" --line-numbers -nL "$chain" 2>/dev/null | \ + sed -e ' + 1d; + 1! { + \#^[0-9]\+ .* /\* '"$comment"' \*/.*$# { + s/ .*$//; + G; h; + } + }; + $!d; + ' | xargs -n1 iptables -t "$table" -D "$chain" 2>/dev/null + } + + delete_rules_by_comment nat nat_reflection_in "$INTERFACE" + delete_rules_by_comment nat nat_reflection_out "$INTERFACE" + delete_rules_by_comment filter nat_reflection_fwd "$INTERFACE" + +elif [ "$ACTION" = "add" ]; then + + prepare_chains() { + iptables -t nat -N nat_reflection_in 2>/dev/null && { + iptables -t nat -A prerouting_rule -j nat_reflection_in + } + + iptables -t nat -N nat_reflection_out 2>/dev/null && { + iptables -t nat -A postrouting_rule -j nat_reflection_out + } + + iptables -t filter -N nat_reflection_fwd 2>/dev/null && { + iptables -t filter -A forwarding_rule -j nat_reflection_fwd + } + } + + find_networks() { + find_networks_cb() { + local cfg="$1" + local zone="$2" + local need_masq="${3:-0}" + + local name + config_get name "$cfg" name + + local masq + config_get_bool masq "$cfg" masq 0 + + [ "$name" = "$zone" ] && [ "$masq" -ge "$need_masq" ] && { + local network + config_get network "$cfg" network + + echo ${network:-$zone} + return 1 + } + } + + config_foreach find_networks_cb zone "$@" + } + + setup_fwd() { + local cfg="$1" + + local reflection + config_get_bool reflection "$cfg" reflection 1 + [ "$reflection" == 1 ] || return + + local src + config_get src "$cfg" src + [ "$src" == "$ZONE" ] || return + + local dest + config_get dest "$cfg" dest + [ "$dest" != "*" ] || return + + local target + config_get target "$cfg" target DNAT + [ "$target" = DNAT ] || return + + prepare_chains + + local net + for net in $(find_networks "$dest" 0); do + local intnet + network_get_subnet intnet "$net" || continue + + local proto + config_get proto "$cfg" proto + + local epmin epmax extport + config_get extport "$cfg" src_dport "1-65535" + [ -n "$extport" ] || return + + epmin="${extport%[-:]*}"; epmax="${extport#*[-:]}" + [ "${epmin#!}" != "$epmax" ] || epmax="" + + local ipmin ipmax intport + config_get intport "$cfg" dest_port "$extport" + + ipmin="${intport%[-:]*}"; ipmax="${intport#*[-:]}" + [ "${ipmin#!}" != "$ipmax" ] || ipmax="" + + local exthost + config_get exthost "$cfg" src_dip "$extip" + + local inthost + config_get inthost "$cfg" dest_ip + [ -n "$inthost" ] || return + + [ "$proto" = all ] && proto="tcp udp" + [ "$proto" = tcpudp ] && proto="tcp udp" + + [ "${inthost#!}" = "$inthost" ] || return 0 + [ "${exthost#!}" = "$exthost" ] || return 0 + + [ "${epmin#!}" != "$epmin" ] && \ + extport="! --dport ${epmin#!}${epmax:+:$epmax}" || \ + extport="--dport $epmin${epmax:+:$epmax}" + + [ "${ipmin#!}" != "$ipmin" ] && \ + intport="! --dport ${ipmin#!}${ipmax:+:$ipmax}" || \ + intport="--dport $ipmin${ipmax:+:$ipmax}" + + local p + for p in ${proto:-tcp udp}; do + case "$p" in + tcp|udp|6|17) + iptables -t nat -A nat_reflection_in \ + -s $intnet -d $exthost \ + -p $p $extport \ + -m comment --comment "$INTERFACE" \ + -j DNAT --to $inthost:${ipmin#!}${ipmax:+-$ipmax} + + iptables -t nat -A nat_reflection_out \ + -s $intnet -d $inthost \ + -p $p $intport \ + -m comment --comment "$INTERFACE" \ + -j SNAT --to-source ${intnet%%/*} + + iptables -t filter -A nat_reflection_fwd \ + -s $intnet -d $inthost \ + -p $p $intport \ + -m comment --comment "$INTERFACE" \ + -j ACCEPT + ;; + esac + done + done + } + + config_load firewall + + local is_masq_zone="$(find_networks "$ZONE" 1)" + [ -n "$is_masq_zone" ] || exit 0 + + local extip + network_get_ipaddr extip "$INTERFACE" || exit 0 + + config_foreach setup_fwd redirect +fi diff --git a/package/network/config/firewall/files/bin/.svn/entries b/package/network/config/firewall/files/bin/.svn/entries new file mode 100644 index 0000000..b14d6a7 --- /dev/null +++ b/package/network/config/firewall/files/bin/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/firewall/files/bin +svn://svn.openwrt.org/openwrt + + + +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +fw +file + + + + +2013-03-17T12:13:19.000000Z +8f07dbd215ae0a8554a76305c508d304 +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + + + + + + + + +686 + diff --git a/package/network/config/firewall/files/bin/.svn/text-base/fw.svn-base b/package/network/config/firewall/files/bin/.svn/text-base/fw.svn-base new file mode 100644 index 0000000..5d20cc8 --- /dev/null +++ b/package/network/config/firewall/files/bin/.svn/text-base/fw.svn-base @@ -0,0 +1,49 @@ +#!/bin/sh +FW_LIBDIR=/lib/firewall + +. /lib/functions.sh +. ${FW_LIBDIR}/fw.sh + +case "$(type fw)" in + *function) ;; + *) exit 255;; +esac + +usage() { + echo $0 "<command>" "<family>" "<table>" "<chain>" "<target>" "{" "<rules>" "}" + exit 0 +} + +cmd=$1 +shift +case "$cmd" in + --help|help) usage ;; + start|stop|reload|restart) + . ${FW_LIBDIR}/core.sh + fw_$cmd + exit $? + ;; +esac + +fam=$1 +shift +case "$fam" in + ip) + fam=i + if [ $# -gt 2 ]; then + for p in $(seq 2 $(($# - 1))); do + if eval "[ \$$p == '}' ]"; then + fam=I + break + fi + done + fi ;; + ip4) fam=4 ;; + ip6) fam=6 ;; + arp) fam=a ;; + eth) fam=e ;; + -*) exec $0 $cmd ${fam##*-} "$@" ;; +esac + +fw "$cmd" "$fam" "$@" +exit $? diff --git a/package/network/config/firewall/files/bin/fw b/package/network/config/firewall/files/bin/fw new file mode 100644 index 0000000..5d20cc8 --- /dev/null +++ b/package/network/config/firewall/files/bin/fw @@ -0,0 +1,49 @@ +#!/bin/sh +FW_LIBDIR=/lib/firewall + +. /lib/functions.sh +. ${FW_LIBDIR}/fw.sh + +case "$(type fw)" in + *function) ;; + *) exit 255;; +esac + +usage() { + echo $0 "<command>" "<family>" "<table>" "<chain>" "<target>" "{" "<rules>" "}" + exit 0 +} + +cmd=$1 +shift +case "$cmd" in + --help|help) usage ;; + start|stop|reload|restart) + . ${FW_LIBDIR}/core.sh + fw_$cmd + exit $? + ;; +esac + +fam=$1 +shift +case "$fam" in + ip) + fam=i + if [ $# -gt 2 ]; then + for p in $(seq 2 $(($# - 1))); do + if eval "[ \$$p == '}' ]"; then + fam=I + break + fi + done + fi ;; + ip4) fam=4 ;; + ip6) fam=6 ;; + arp) fam=a ;; + eth) fam=e ;; + -*) exec $0 $cmd ${fam##*-} "$@" ;; +esac + +fw "$cmd" "$fam" "$@" +exit $? diff --git a/package/network/config/firewall/files/firewall.config b/package/network/config/firewall/files/firewall.config new file mode 100644 index 0000000..6acfe1e --- /dev/null +++ b/package/network/config/firewall/files/firewall.config @@ -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 + option network 'lan' + option input ACCEPT + option output ACCEPT + option forward REJECT + +config zone + option name wan + option network 'wan' + 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 + +# 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 fe80::/10 + option src_port 547 + option dest_ip fe80::/10 + option dest_port 546 + 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 + +# Block ULA-traffic from leaking out +config rule + option name Enforce-ULA-Border-Src + option src * + option dest wan + option proto all + option src_ip fc00::/7 + option family ipv6 + option target REJECT + +config rule + option name Enforce-ULA-Border-Dest + option src * + option dest wan + option proto all + option dest_ip fc00::/7 + option family ipv6 + option target REJECT + +# 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 + +# allow IPsec/ESP and ISAKMP passthrough +#config rule +# option src wan +# option dest lan +# option protocol esp +# option target ACCEPT + +#config rule +# option src wan +# option dest lan +# option src_port 500 +# option dest_port 500 +# option proto udp +# option target ACCEPT + +### 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 diff --git a/package/network/config/firewall/files/firewall.hotplug b/package/network/config/firewall/files/firewall.hotplug new file mode 100644 index 0000000..52e7798 --- /dev/null +++ b/package/network/config/firewall/files/firewall.hotplug @@ -0,0 +1,22 @@ +#!/bin/sh +# This script is executed as part of the hotplug event with +# HOTPLUG_TYPE=iface, triggered by various scripts when an interface +# is configured (ACTION=ifup) or deconfigured (ACTION=ifdown). The +# interface is available as INTERFACE, the real device as DEVICE. + +[ "$DEVICE" == "lo" ] && exit 0 + +. /lib/functions.sh +. /lib/firewall/core.sh + +fw_init +fw_is_loaded || exit 0 + +case "$ACTION" in + ifup) + fw_configure_interface "$INTERFACE" add "$DEVICE" & + ;; + ifdown) + fw_configure_interface "$INTERFACE" del "$DEVICE" + ;; +esac diff --git a/package/network/config/firewall/files/firewall.init b/package/network/config/firewall/files/firewall.init new file mode 100755 index 0000000..a2fd0a0 --- /dev/null +++ b/package/network/config/firewall/files/firewall.init @@ -0,0 +1,27 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008-2010 OpenWrt.org + +START=45 + +FW_LIBDIR=/lib/firewall + +fw() { + . $FW_LIBDIR/core.sh + fw_$1 +} + +start() { + fw start +} + +stop() { + fw stop +} + +restart() { + fw restart +} + +reload() { + fw reload +} diff --git a/package/network/config/firewall/files/firewall.upgrade b/package/network/config/firewall/files/firewall.upgrade new file mode 100644 index 0000000..64f63eb --- /dev/null +++ b/package/network/config/firewall/files/firewall.upgrade @@ -0,0 +1 @@ +/etc/firewall.user diff --git a/package/network/config/firewall/files/firewall.user b/package/network/config/firewall/files/firewall.user new file mode 100644 index 0000000..1ccbd01 --- /dev/null +++ b/package/network/config/firewall/files/firewall.user @@ -0,0 +1,4 @@ +# This file is interpreted as shell script. +# Put your custom iptables rules here, they will +# be executed with each firewall (re-)start. + diff --git a/package/network/config/firewall/files/lib/.svn/entries b/package/network/config/firewall/files/lib/.svn/entries new file mode 100644 index 0000000..1b64086 --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/entries @@ -0,0 +1,334 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/firewall/files/lib +svn://svn.openwrt.org/openwrt + + + +2013-02-22T13:45:20.660376Z +35745 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +core.sh +file + + + + +2013-03-17T12:13:19.000000Z +57cde5df70cac74fcf1c491189ab28f2 +2012-03-18T23:34:06.984635Z +31014 +jow + + + + + + + + + + + + + + + + + + + + + +2765 + +core_interface.sh +file + + + + +2013-03-17T12:13:19.000000Z +4039e9bc29cadde4210e901e197e9509 +2013-02-04T14:38:33.835622Z +35484 +jow + + + + + + + + + + + + + + + + + + + + + +6351 + +core_redirect.sh +file + + + + +2013-03-17T12:13:19.000000Z +7e4a93fc56d528edacc9dcebbf18b5dd +2013-02-04T14:38:33.835622Z +35484 +jow + + + + + + + + + + + + + + + + + + + + + +4006 + +core_forwarding.sh +file + + + + +2013-03-17T12:13:19.000000Z +f835e6555c82efbdf000ce091b824fad +2013-02-04T14:38:33.835622Z +35484 +jow + + + + + + + + + + + + + + + + + + + + + +1087 + +core_init.sh +file + + + + +2013-03-17T12:13:19.000000Z +d9e95ae46c439896e622c8d019ad71f7 +2013-02-22T13:45:20.660376Z +35745 +jow + + + + + + + + + + + + + + + + + + + + + +8941 + +fw.sh +file + + + + +2013-03-17T12:13:19.000000Z +aada254fdb297fc3bdd44a97272a9f8b +2013-02-04T14:38:33.835622Z +35484 +jow + + + + + + + + + + + + + + + + + + + + + +6991 + +core_rule.sh +file + + + + +2013-03-17T12:13:19.000000Z +eabaaff4f9126ce46d9a67eb278a9bef +2013-02-04T14:38:33.835622Z +35484 +jow + + + + + + + + + + + + + + + + + + + + + +2887 + +config.sh +file + + + + +2013-03-17T12:13:19.000000Z +472688de7ea0aabacfc30480a4b4eef9 +2011-12-20T01:10:15.660680Z +29577 +jow + + + + + + + + + + + + + + + + + + + + + +2296 + +uci_firewall.sh +file + + + + +2013-03-17T12:13:19.000000Z +068ecea3916f58dccb235d0d26d7fc43 +2010-05-01T18:22:01.443052Z +21286 +jow + + + + + + + + + + + + + + + + + + + + + +172 + diff --git a/package/network/config/firewall/files/lib/.svn/text-base/config.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/config.sh.svn-base new file mode 100644 index 0000000..8b2399f --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/config.sh.svn-base @@ -0,0 +1,101 @@ +# Copyright (C) 2009-2010 OpenWrt.org +# Copyright (C) 2009 Malte S. Stretz <http://msquadrat.de> +# +# This is a temporary file, I hope to have some of this stuff merged into +# /lib/functions.sh (without the fw_ prefix of course) one day. + +fw_config_append() { # <package> + CONFIG_APPEND=1 config_load "$@" + unset CONFIG_APPEND +} + +fw_config_once() { # <function> <type> + local func=$1 + local type=$2 + shift 2 + + local config=cfg00nil + fw_config__once() { + config=$1 + } + config_foreach fw_config__once "$type" + + $func $config "$@" +} + +fw_config_get_section() { # <config> <prefix> <type> <name> <default> ... + local config=$1 + local prefix=$2 + shift 2 + + [ -n "$config" ] || return 1 + [ -n "$prefix" ] && { + prefix="${prefix}_" + export ${NO_EXPORT:+-n} -- "${prefix}NAME"="${config}" + config_get "${prefix}TYPE" "$config" TYPE + } + + local enabled + config_get_bool enabled "$config" enabled 1 + [ $enabled -eq 1 ] || return 1 + + [ "$1" == '{' ] && shift + while [ $# -ge 3 ]; do + local type=$1 + local name=$2 + local dflt=$3 + shift 3 + # TODO: Move handling of defaults to /lib/functions.sh + # and get replace the case block with the following + # two lines: + # type=${type#string} + # config_get${type:+_${type}} "${prefix}${name}" "$config" "$name" "$dflt" || return + case "$type" in + string) + local tmp + config_get tmp "$config" "$name" || return + [ -z "$tmp" ] && tmp=$dflt + export ${NO_EXPORT:+-n} -- "${prefix}${name}=${tmp}" + continue + ;; + boolean) + type=bool + ;; + esac; + + local cmd=${prefix}config_get_${type} + type $cmd > /dev/null || { + cmd=config_get_${type} + } + type $cmd > /dev/null || { + echo "config type $type (for $name) not supported" >&2 + return 1 + } + $cmd "${prefix}${name}" "$config" "$name" "$dflt" || return + done +} + +config_get_ipaddr() { + local varn=$1 + local conf=$2 + local name=$3 + local dflt=$4 + + local addr + config_get addr "$conf" "$name" || return + [ -n "$addr" ] || addr=$dflt + + local mask=${addr#*/} + [ "$mask" != "$addr" ] || mask= + addr=${addr%/*} + + local vers= + case "$addr" in + *:*) vers=6; mask="${mask:-128}" ;; + *.*) vers=4; mask="${mask:-32}" ;; + esac + + export ${NO_EXPORT:+-n} -- "${varn}=${addr}" + export ${NO_EXPORT:+-n} -- "${varn}_prefixlen=${mask}" + export ${NO_EXPORT:+-n} -- "${varn}_version=${vers}" +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/core.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/core.sh.svn-base new file mode 100644 index 0000000..93d4d2e --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/core.sh.svn-base @@ -0,0 +1,159 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +FW_LIBDIR=${FW_LIBDIR:-/lib/firewall} + +. $FW_LIBDIR/fw.sh +include /lib/network + +fw_start() { + fw_init + + FW_DEFAULTS_APPLIED= + + fw_is_loaded && { + echo "firewall already loaded" >&2 + exit 1 + } + + uci_set_state firewall core "" firewall_state + + fw_clear DROP + + fw_callback pre core + + echo "Loading defaults" + fw_config_once fw_load_defaults defaults + + echo "Loading zones" + config_foreach fw_load_zone zone + + echo "Loading forwardings" + config_foreach fw_load_forwarding forwarding + + echo "Loading rules" + config_foreach fw_load_rule rule + + echo "Loading redirects" + config_foreach fw_load_redirect redirect + + echo "Loading includes" + config_foreach fw_load_include include + + [ -z "$FW_NOTRACK_DISABLED" ] && { + echo "Optimizing conntrack" + config_foreach fw_load_notrack_zone zone + } + + echo "Loading interfaces" + config_foreach fw_configure_interface interface add + + fw_callback post core + + uci_set_state firewall core zones "$FW_ZONES" + uci_set_state firewall core loaded 1 +} + +fw_stop() { + fw_init + + fw_callback pre stop + + local z n i + config_get z core zones + for z in $z; do + config_get n core "${z}_networks" + for n in $n; do + config_get i core "${n}_ifname" + [ -n "$i" ] && env -i ACTION=remove ZONE="$z" \ + INTERFACE="$n" DEVICE="$i" /sbin/hotplug-call firewall + done + + config_get i core "${z}_tcpmss" + [ "$i" == 1 ] && { + fw del i m FORWARD zone_${z}_MSSFIX + fw del i m zone_${z}_MSSFIX + } + done + + fw_clear ACCEPT + + fw_callback post stop + + uci_revert_state firewall + config_clear + + local h + for h in $FW_HOOKS; do unset $h; done + + unset FW_HOOKS + unset FW_INITIALIZED +} + +fw_restart() { + fw_stop + fw_start +} + +fw_reload() { + fw_restart +} + +fw_is_loaded() { + local bool=$(uci_get_state firewall.core.loaded) + return $((! ${bool:-0})) +} + + +fw_die() { + echo "Error:" "$@" >&2 + fw_log error "$@" + fw_stop + exit 1 +} + +fw_log() { + local level="$1" + [ -n "$2" ] && shift || level=notice + [ "$level" != error ] || echo "Error: $@" >&2 + logger -t firewall -p user.$level "$@" +} + + +fw_init() { + [ -z "$FW_INITIALIZED" ] || return 0 + + . $FW_LIBDIR/config.sh + + scan_interfaces + fw_config_append firewall + + local hooks="core stop defaults zone notrack synflood" + local file lib hk pp + for file in $FW_LIBDIR/core_*.sh; do + . $file + hk=$(basename $file .sh) + hk=${hk#core_} + append hooks $hk + done + for file in $FW_LIBDIR/*.sh; do + lib=$(basename $file .sh) + lib=${lib##[0-9][0-9]_} + case $lib in + core*|fw|config|uci_firewall) continue ;; + esac + . $file + for hk in $hooks; do + for pp in pre post; do + type ${lib}_${pp}_${hk}_cb >/dev/null && { + append FW_CB_${pp}_${hk} ${lib} + append FW_HOOKS FW_CB_${pp}_${hk} + } + done + done + done + + fw_callback post init + + FW_INITIALIZED=1 + return 0 +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/core_forwarding.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/core_forwarding.sh.svn-base new file mode 100644 index 0000000..2ea03f0 --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/core_forwarding.sh.svn-base @@ -0,0 +1,44 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +fw_config_get_forwarding() { + [ "${forwarding_NAME}" != "$1" ] || return + fw_config_get_section "$1" forwarding { \ + string _name "$1" \ + string name "" \ + string src "" \ + string dest "" \ + string family "" \ + } || return + [ -n "$forwarding_name" ] || forwarding_name=$forwarding__name +} + +fw_load_forwarding() { + fw_config_get_forwarding "$1" + + fw_callback pre forwarding + + local chain=delegate_forward + [ -n "$forwarding_src" ] && { + chain=zone_${forwarding_src}_forward + } + + local target=ACCEPT + [ -n "$forwarding_dest" ] && { + target=zone_${forwarding_dest}_dest_ACCEPT + } + + local mode + fw_get_family_mode mode ${forwarding_family:-x} ${forwarding_dest:-${forwarding_src:--}} i + + fw add $mode f $chain $target ^ + + # propagate masq zone flag + [ -n "$forwarding_src" ] && list_contains FW_CONNTRACK_ZONES $forwarding_src && { + append FW_CONNTRACK_ZONES $forwarding_dest + } + [ -n "$forwarding_dest" ] && list_contains FW_CONNTRACK_ZONES $forwarding_dest && { + append FW_CONNTRACK_ZONES $forwarding_src + } + + fw_callback post forwarding +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/core_init.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/core_init.sh.svn-base new file mode 100644 index 0000000..404a836 --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/core_init.sh.svn-base @@ -0,0 +1,361 @@ +# Copyright (C) 2009-2011 OpenWrt.org +# Copyright (C) 2008 John Crispin <blogic@openwrt.org> + +FW_INITIALIZED= + +FW_ZONES= +FW_ZONES4= +FW_ZONES6= +FW_CONNTRACK_ZONES= +FW_NOTRACK_DISABLED= + +FW_DEFAULTS_APPLIED= +FW_ADD_CUSTOM_CHAINS= +FW_ACCEPT_REDIRECTS= +FW_ACCEPT_SRC_ROUTE= + +FW_DEFAULT_INPUT_POLICY=REJECT +FW_DEFAULT_OUTPUT_POLICY=REJECT +FW_DEFAULT_FORWARD_POLICY=REJECT + +FW_DISABLE_IPV4=0 +FW_DISABLE_IPV6=0 + + +fw_load_defaults() { + fw_config_get_section "$1" defaults { \ + string input $FW_DEFAULT_INPUT_POLICY \ + string output $FW_DEFAULT_OUTPUT_POLICY \ + string forward $FW_DEFAULT_FORWARD_POLICY \ + boolean drop_invalid 0 \ + boolean syn_flood 0 \ + boolean synflood_protect 0 \ + string synflood_rate 25 \ + string synflood_burst 50 \ + boolean tcp_syncookies 1 \ + boolean tcp_ecn 0 \ + boolean tcp_westwood 0 \ + boolean tcp_window_scaling 1 \ + boolean accept_redirects 0 \ + boolean accept_source_route 0 \ + boolean custom_chains 1 \ + boolean disable_ipv6 0 \ + } || return + [ -n "$FW_DEFAULTS_APPLIED" ] && { + fw_log error "duplicate defaults section detected, skipping" + return 1 + } + FW_DEFAULTS_APPLIED=1 + + FW_DEFAULT_INPUT_POLICY=$defaults_input + FW_DEFAULT_OUTPUT_POLICY=$defaults_output + FW_DEFAULT_FORWARD_POLICY=$defaults_forward + + FW_ADD_CUSTOM_CHAINS=$defaults_custom_chains + + FW_ACCEPT_REDIRECTS=$defaults_accept_redirects + FW_ACCEPT_SRC_ROUTE=$defaults_accept_source_route + + FW_DISABLE_IPV6=$defaults_disable_ipv6 + + fw_callback pre defaults + + # Seems like there are only one sysctl for both IP versions. + for s in syncookies ecn westwood window_scaling; do + eval "sysctl -e -w net.ipv4.tcp_${s}=\$defaults_tcp_${s}" >/dev/null + done + fw_sysctl_interface all + + fw add i f INPUT ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED } + fw add i f OUTPUT ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED } + fw add i f FORWARD ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED } + + [ $defaults_drop_invalid == 1 ] && { + fw add i f INPUT DROP { -m conntrack --ctstate INVALID } + fw add i f OUTPUT DROP { -m conntrack --ctstate INVALID } + fw add i f FORWARD DROP { -m conntrack --ctstate INVALID } + FW_NOTRACK_DISABLED=1 + } + + fw add i f INPUT ACCEPT { -i lo } + fw add i f OUTPUT ACCEPT { -o lo } + + # Compatibility to old 'syn_flood' parameter + [ $defaults_syn_flood == 1 ] && \ + defaults_synflood_protect=1 + + [ "${defaults_synflood_rate%/*}" == "$defaults_synflood_rate" ] && \ + defaults_synflood_rate="$defaults_synflood_rate/second" + + [ $defaults_synflood_protect == 1 ] && { + echo "Loading synflood protection" + fw_callback pre synflood + fw add i f syn_flood + fw add i f syn_flood RETURN { \ + -p tcp --syn \ + -m limit --limit "${defaults_synflood_rate}" --limit-burst "${defaults_synflood_burst}" \ + } + fw add i f syn_flood DROP + fw add i f INPUT syn_flood { -p tcp --syn } + fw_callback post synflood + } + + [ $defaults_custom_chains == 1 ] && { + echo "Adding custom chains" + fw add i f input_rule + fw add i f output_rule + fw add i f forwarding_rule + fw add i n prerouting_rule + fw add i n postrouting_rule + + fw add i f INPUT input_rule + fw add i f OUTPUT output_rule + fw add i f FORWARD forwarding_rule + fw add i n PREROUTING prerouting_rule + fw add i n POSTROUTING postrouting_rule + } + + fw add i f delegate_input + fw add i f delegate_output + fw add i f delegate_forward + + fw add i f INPUT delegate_input + fw add i f OUTPUT delegate_output + fw add i f FORWARD delegate_forward + + fw add i f reject + fw add i f reject REJECT { --reject-with tcp-reset -p tcp } + fw add i f reject REJECT { --reject-with port-unreach } + + fw_set_filter_policy + + fw_callback post defaults +} + + +fw_config_get_zone() { + [ "${zone_NAME}" != "$1" ] || return + fw_config_get_section "$1" zone { \ + string name "$1" \ + string network "" \ + string device "" \ + string subnet "" \ + string input "$FW_DEFAULT_INPUT_POLICY" \ + string output "$FW_DEFAULT_OUTPUT_POLICY" \ + string forward "$FW_DEFAULT_FORWARD_POLICY" \ + boolean masq 0 \ + string masq_src "" \ + string masq_dest "" \ + string extra "" \ + string extra_src "" \ + string extra_dest "" \ + boolean conntrack 0 \ + boolean mtu_fix 0 \ + boolean custom_chains 0 \ + boolean log 0 \ + string log_limit 10 \ + string family "" \ + } || return + [ -n "$zone_name" ] || zone_name=$zone_NAME + [ -n "$zone_extra_src" ] || zone_extra_src="$zone_extra" + [ -n "$zone_extra_dest" ] || zone_extra_dest="$zone_extra" + [ -n "$zone_network$zone_subnet$zone_device$zone_extra_src$zone_extra_dest" ] || zone_network=$zone_name +} + +fw_load_zone() { + fw_config_get_zone "$1" + + list_contains FW_ZONES $zone_name && { + fw_log error "zone ${zone_name}: duplicated zone, skipping" + return 0 + } + append FW_ZONES $zone_name + + fw_callback pre zone + + [ $zone_conntrack = 1 -o $zone_masq = 1 ] && \ + append FW_CONNTRACK_ZONES "$zone_name" + + local mode + case "$zone_family" in + *4) + mode=4 + append FW_ZONES4 $zone_name + uci_set_state firewall core ${zone_name}_ipv4 1 + ;; + *6) + mode=6 + append FW_ZONES6 $zone_name + uci_set_state firewall core ${zone_name}_ipv6 1 + ;; + *) + mode=i + append FW_ZONES4 $zone_name + append FW_ZONES6 $zone_name + uci_set_state firewall core ${zone_name}_ipv4 1 + uci_set_state firewall core ${zone_name}_ipv6 1 + ;; + esac + + local chain=zone_${zone_name} + + fw add $mode f ${chain}_src_ACCEPT + fw add $mode f ${chain}_src_DROP + fw add $mode f ${chain}_src_REJECT + + fw add $mode f ${chain}_dest_ACCEPT + fw add $mode f ${chain}_dest_DROP + fw add $mode f ${chain}_dest_REJECT + + fw add $mode f ${chain}_input + fw add $mode f ${chain}_input ${chain}_src_${zone_input} $ + + fw add $mode f ${chain}_forward + fw add $mode f ${chain}_forward ${chain}_dest_${zone_forward} $ + + fw add $mode f ${chain}_output + fw add $mode f ${chain}_output ${chain}_dest_${zone_output} $ + + # TODO: Rename to ${chain}_MASQUERADE + fw add $mode n ${chain}_nat + fw add $mode n ${chain}_prerouting + + fw add $mode r ${chain}_notrack + + [ $zone_mtu_fix == 1 ] && { + fw add $mode m ${chain}_MSSFIX + fw add $mode m FORWARD ${chain}_MSSFIX ^ + uci_set_state firewall core ${zone_name}_tcpmss 1 + } + + [ $zone_custom_chains == 1 ] && { + [ $FW_ADD_CUSTOM_CHAINS == 1 ] || \ + fw_die "zone ${zone_name}: custom_chains globally disabled" + + fw add $mode f input_${zone_name} + fw add $mode f ${chain}_input input_${zone_name} ^ + + fw add $mode f forwarding_${zone_name} + fw add $mode f ${chain}_forward forwarding_${zone_name} ^ + + fw add $mode n prerouting_${zone_name} + fw add $mode n ${chain}_prerouting prerouting_${zone_name} ^ + } + + [ "$zone_log" == 1 ] && { + [ "${zone_log_limit%/*}" == "$zone_log_limit" ] && \ + zone_log_limit="$zone_log_limit/minute" + + local t + for t in REJECT DROP; do + local d + for d in src dest; do + fw add $mode f ${chain}_${d}_${t} LOG ^ \ + { -m limit --limit $zone_log_limit --log-prefix "$t($d:$zone_name): " } + done + done + + [ $zone_mtu_fix == 1 ] && \ + fw add $mode m ${chain}_MSSFIX LOG ^ \ + { -p tcp --tcp-flags SYN,RST SYN -m limit --limit $zone_log_limit --log-prefix "MSSFIX($zone_name): " } + } + + # NB: if MASQUERADING for IPv6 becomes available we'll need a family check here + if [ "$zone_masq" == 1 ]; then + local msrc mdst + for msrc in ${zone_masq_src:-0.0.0.0/0}; do + case "$msrc" in + *.*) fw_get_negation msrc '-s' "$msrc" ;; + *) fw_get_subnet4 msrc '-s' "$msrc" || break ;; + esac + + for mdst in ${zone_masq_dest:-0.0.0.0/0}; do + case "$mdst" in + *.*) fw_get_negation mdst '-d' "$mdst" ;; + *) fw_get_subnet4 mdst '-d' "$mdst" || break ;; + esac + + fw add $mode n ${chain}_nat MASQUERADE $ { $msrc $mdst } + done + done + fi + + local dev + for dev in ${zone_device:-""}; do + local net + for net in ${zone_subnet:-""}; do + [ -n "$dev" ] || [ -n "$net" ] || continue + fw_do_interface_rules add "${zone_name}" "$dev" "$net" \ + "${zone_extra_src}" "${zone_extra_dest}" + done + done + + fw_callback post zone +} + +fw_load_notrack_zone() { + fw_config_get_zone "$1" + list_contains FW_CONNTRACK_ZONES "${zone_name}" && return + + fw_callback pre notrack + + fw add i r zone_${zone_name}_notrack NOTRACK $ + + fw_callback post notrack +} + + +fw_load_include() { + local name="$1" + + local path + config_get path ${name} path + + [ -e $path ] && ( + config() { + fw_log error "You cannot use UCI in firewall includes!" >&2 + exit 1 + } + . $path + ) +} + + +fw_clear() { + local policy=$1 + + fw_set_filter_policy $policy + + local tab + for tab in f n r; do + fw del i $tab + done +} + +fw_set_filter_policy() { + local policy=$1 + + local chn tgt + for chn in INPUT OUTPUT FORWARD; do + eval "tgt=\${policy:-\${FW_DEFAULT_${chn}_POLICY}}" + [ $tgt == "REJECT" ] && tgt=reject + [ $tgt == "ACCEPT" -o $tgt == "DROP" ] || { + fw add i f $chn $tgt $ + tgt=DROP + } + fw policy i f $chn $tgt + done +} + + +fw_callback() { + local pp=$1 + local hk=$2 + + local libs lib + eval "libs=\$FW_CB_${pp}_${hk}" + [ -n "$libs" ] || return + for lib in $libs; do + ${lib}_${pp}_${hk}_cb + done +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/core_interface.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/core_interface.sh.svn-base new file mode 100644 index 0000000..9138cbf --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/core_interface.sh.svn-base @@ -0,0 +1,214 @@ +# Copyright (C) 2009-2013 OpenWrt.org + +fw__uci_state_add() { + local var="$1" + local item="$2" + + local val="$(uci_get_state firewall core $var)" + local e1; for e1 in $item; do + local e2; for e2 in $val; do + [ "$e1" = "$e2" ] && e1="" + done + val="${val:+$val${e1:+ }}$e1" + done + + uci_toggle_state firewall core $var "$val" +} + +fw__uci_state_del() { + local var="$1" + local item="$2" + + local rest="" + local val="$(uci_get_state firewall core $var)" + local e1; for e1 in $val; do + local e2; for e2 in $item; do + [ "$e1" = "$e2" ] && e1="" + done + rest="${rest:+$rest${e1:+ }}$e1" + done + + uci_toggle_state firewall core $var "$rest" +} + +fw_do_interface_rules() { + local action=$1 + local zone=$2 + local chain=zone_${zone} + local ifname=$3 + local subnet=$4 + local extra_src="$5" + local extra_dest="$6" + + local idev odev inet onet mode + fw_get_family_mode mode x $zone i + + fw_get_negation idev '-i' "$ifname" + fw_get_negation odev '-o' "$ifname" + + case "$mode/$subnet" in + # Zone supports v6 only or dual, need v6 + G6/*:*|i/*:*) + fw_get_negation inet '-s' "$subnet" + fw_get_negation onet '-d' "$subnet" + mode=6 + ;; + + # Zone supports v4 only or dual, need v4 + G4/*.*.*.*|i/*.*.*.*) + fw_get_negation inet '-s' "$subnet" + fw_get_negation onet '-d' "$subnet" + mode=4 + ;; + + # Need v6 while zone is v4 + */*:*) fw_log info "zone $zone does not support IPv6 address family, skipping"; return ;; + + # Need v4 while zone is v6 + */*.*) fw_log info "zone $zone does not support IPv4 address family, skipping"; return ;; + + # Strip prefix + *) mode="${mode#G}" ;; + esac + + lock /var/run/firewall-interface.lock + + fw $action $mode f ${chain}_dest_ACCEPT ACCEPT $ { $odev $onet $extra_dest } + fw $action $mode f ${chain}_src_ACCEPT ACCEPT $ { $idev $inet $extra_src } + fw $action $mode f ${chain}_dest_DROP DROP $ { $odev $onet $extra_dest } + fw $action $mode f ${chain}_src_DROP DROP $ { $idev $inet $extra_src } + fw $action $mode f ${chain}_dest_REJECT reject $ { $odev $onet $extra_dest } + fw $action $mode f ${chain}_src_REJECT reject $ { $idev $inet $extra_src } + + [ "$(uci_get_state firewall core "${zone}_tcpmss")" == 1 ] && \ + fw $action $mode m ${chain}_MSSFIX TCPMSS $ \ + { $odev -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu $onet $extra_dest } + + fw $action $mode f delegate_input ${chain}_input $ { $idev $inet $extra_src } + fw $action $mode f delegate_forward ${chain}_forward $ { $idev $inet $extra_src } + fw $action $mode f delegate_output ${chain}_output $ { $odev $onet $extra_dest } + + fw $action $mode n PREROUTING ${chain}_prerouting $ { $idev $inet $extra_src } + fw $action $mode r PREROUTING ${chain}_notrack $ { $idev $inet $extra_src } + fw $action $mode n POSTROUTING ${chain}_nat $ { $odev $onet $extra_dest } + + # Flush conntrack table + echo f >/proc/net/nf_conntrack 2>/dev/null + + lock -u /var/run/firewall-interface.lock +} + +fw_configure_interface() { + local iface=$1 + local action=$2 + local ifname=$3 + local aliasnet=$4 + + [ "$action" == "add" ] && { + local status=$(uci_get_state network "$iface" up 0) + [ "$status" == 1 ] || [ -n "$aliasnet" ] || return 0 + } + + [ -n "$ifname" ] || { + ifname=$(uci_get_state network "$iface" ifname) + ifname="${ifname%%:*}" + [ -z "$ifname" ] && return 0 + } + + [ "$ifname" == "lo" ] && return 0 + + fw_callback pre interface + + local old_zones old_ifname old_subnets + config_get old_zones core "${iface}_zone" + [ -n "$old_zones" ] && { + config_get old_ifname core "${iface}_ifname" + config_get old_subnets core "${iface}_subnets" + + local z + for z in $old_zones; do + local n + for n in ${old_subnets:-""}; do + fw_log info "removing $iface ($old_ifname${n:+ alias $n}) from zone $z" + fw_do_interface_rules del $z $old_ifname $n + done + + [ -n "$old_subnets" ] || { + fw__uci_state_del "${z}_networks" "$iface" + env -i ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall + } + done + + local old_aliases + config_get old_aliases core "${iface}_aliases" + + local a + for a in $old_aliases; do + fw_configure_interface "$a" del "$old_ifname" + done + + uci_revert_state firewall core "${iface}_zone" + uci_revert_state firewall core "${iface}_ifname" + uci_revert_state firewall core "${iface}_subnets" + uci_revert_state firewall core "${iface}_aliases" + } + + [ "$action" == del ] && return + + [ -z "$aliasnet" ] && { + local aliases + config_get aliases "$iface" aliases + + local a + for a in $aliases; do + local ipaddr netmask ip6addr + config_get ipaddr "$a" ipaddr + config_get netmask "$a" netmask + config_get ip6addr "$a" ip6addr + + [ -n "$ipaddr" ] && fw_configure_interface "$a" add "" "$ipaddr${netmask:+/$netmask}" + [ -n "$ip6addr" ] && fw_configure_interface "$a" add "" "$ip6addr" + done + + fw_sysctl_interface $ifname + fw_callback post interface + + uci_toggle_state firewall core "${iface}_aliases" "$aliases" + } || { + local subnets= + config_get subnets core "${iface}_subnets" + append subnets "$aliasnet" + + config_set core "${iface}_subnets" "$subnets" + uci_toggle_state firewall core "${iface}_subnets" "$subnets" + } + + local new_zones= + load_zone() { + fw_config_get_zone "$1" + list_contains zone_network "$iface" || return + + fw_log info "adding $iface ($ifname${aliasnet:+ alias $aliasnet}) to zone $zone_name" + fw_do_interface_rules add ${zone_name} "$ifname" "$aliasnet" + append new_zones $zone_name + + [ -n "$aliasnet" ] || { + fw__uci_state_add "${zone_name}_networks" "${zone_network}" + env -i ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall + } + } + config_foreach load_zone zone + + uci_toggle_state firewall core "${iface}_zone" "$new_zones" + uci_toggle_state firewall core "${iface}_ifname" "$ifname" +} + +fw_sysctl_interface() { + local ifname=$1 + { + sysctl -w net.ipv4.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS + sysctl -w net.ipv6.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS + sysctl -w net.ipv4.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE + sysctl -w net.ipv6.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE + } >/dev/null 2>/dev/null +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/core_redirect.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/core_redirect.sh.svn-base new file mode 100644 index 0000000..9493bc6 --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/core_redirect.sh.svn-base @@ -0,0 +1,130 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +fw_config_get_redirect() { + [ "${redirect_NAME}" != "$1" ] || return + fw_config_get_section "$1" redirect { \ + string _name "$1" \ + string name "" \ + string src "" \ + ipaddr src_ip "" \ + ipaddr src_dip "" \ + string src_mac "" \ + string src_port "" \ + string src_dport "" \ + string dest "" \ + ipaddr dest_ip "" \ + string dest_port "" \ + string proto "tcpudp" \ + string family "" \ + string target "DNAT" \ + string extra "" \ + } || return + [ -n "$redirect_name" ] || redirect_name=$redirect__name +} + +fw_load_redirect() { + fw_config_get_redirect "$1" + + fw_callback pre redirect + + local fwdchain natchain natopt nataddr natports srcdaddr srcdports + if [ "$redirect_target" == "DNAT" ]; then + [ -n "${redirect_src#*}" -a -n "$redirect_dest_ip$redirect_dest_port" ] || { + fw_log error "DNAT redirect ${redirect_name}: needs src and dest_ip or dest_port, skipping" + return 0 + } + + fwdopt="" + fwdchain="" + + # Check whether only ports are given or whether the given dest ip is local, + # in this case match only DNATed traffic and allow it on input, not forward + if [ -z "$redirect_dest_ip" ] || /sbin/ifconfig | grep -qE "addr:${redirect_dest_ip//./\\.}\b"; then + fwdopt="-m conntrack --ctstate DNAT" + fwdchain="zone_${redirect_src}_input" + else + fwdchain="zone_${redirect_src}_forward" + fi + + natopt="--to-destination" + natchain="zone_${redirect_src}_prerouting" + nataddr="$redirect_dest_ip" + fw_get_port_range natports "${redirect_dest_port#!}" "-" + + fw_get_negation srcdaddr '-d' "${redirect_src_dip:+$redirect_src_dip/$redirect_src_dip_prefixlen}" + fw_get_port_range srcdports "$redirect_src_dport" ":" + fw_get_negation srcdports '--dport' "$srcdports" + + list_contains FW_CONNTRACK_ZONES $redirect_src || \ + append FW_CONNTRACK_ZONES $redirect_src + + elif [ "$redirect_target" == "SNAT" ]; then + [ -n "${redirect_dest#*}" -a -n "$redirect_src_dip" ] || { + fw_log error "SNAT redirect ${redirect_name}: needs dest and src_dip, skipping" + return 0 + } + + fwdchain="${redirect_src:+zone_${redirect_src}_forward}" + + natopt="--to-source" + natchain="zone_${redirect_dest}_nat" + nataddr="$redirect_src_dip" + fw_get_port_range natports "${redirect_src_dport#!}" "-" + + fw_get_negation srcdaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" + fw_get_port_range srcdports "$redirect_dest_port" ":" + fw_get_negation srcdports '--dport' "$srcdports" + + list_contains FW_CONNTRACK_ZONES $redirect_dest || \ + append FW_CONNTRACK_ZONES $redirect_dest + + else + fw_log error "redirect ${redirect_name}: target must be either DNAT or SNAT, skipping" + return 0 + fi + + local mode + fw_get_family_mode mode ${redirect_family:-x} ${redirect_src:-$redirect_dest} I + + local srcaddr + fw_get_negation srcaddr '-s' "${redirect_src_ip:+$redirect_src_ip/$redirect_src_ip_prefixlen}" + + local srcports + fw_get_port_range srcports "$redirect_src_port" ":" + fw_get_negation srcports '--sport' "$srcports" + + local destaddr + fw_get_negation destaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" + + local destports + fw_get_port_range destports "${redirect_dest_port:-$redirect_src_dport}" ":" + fw_get_negation destports '--dport' "$destports" + + [ "$redirect_proto" == "tcpudp" ] && redirect_proto="tcp udp" + local pr; for pr in $redirect_proto; do + fw_get_negation pr '-p' "$pr" + local sm; for sm in ${redirect_src_mac:-""}; do + fw_get_negation sm '--mac-source' "$sm" + fw add $mode n $natchain $redirect_target + \ + { $redirect_src_ip $redirect_dest_ip } { \ + $srcaddr $srcdaddr $pr \ + $srcports $srcdports \ + ${sm:+-m mac $sm} \ + $natopt $nataddr${natports:+:$natports} \ + $redirect_options \ + } + + fw add $mode f ${fwdchain:-delegate_forward} ACCEPT + \ + { $redirect_src_ip $redirect_dest_ip } { \ + $srcaddr $destaddr \ + $pr \ + $srcports $destports \ + ${sm:+-m mac $sm} \ + $fwdopt \ + $redirect_extra \ + } + done + done + + fw_callback post redirect +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/core_rule.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/core_rule.sh.svn-base new file mode 100644 index 0000000..0ce2122 --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/core_rule.sh.svn-base @@ -0,0 +1,117 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +fw_config_get_rule() { + [ "${rule_NAME}" != "$1" ] || return + fw_config_get_section "$1" rule { \ + string _name "$1" \ + string name "" \ + string src "" \ + ipaddr src_ip "" \ + string src_mac "" \ + string src_port "" \ + string dest "" \ + ipaddr dest_ip "" \ + string dest_port "" \ + string icmp_type "" \ + string proto "tcpudp" \ + string target "" \ + string family "" \ + string limit "" \ + string limit_burst "" \ + string extra "" \ + } || return + [ -n "$rule_name" ] || rule_name=$rule__name +} + +fw_load_rule() { + fw_config_get_rule "$1" + + [ "$rule_target" != "NOTRACK" ] || [ -n "$rule_src" ] || [ "$rule_src" != "*" ] || { + fw_log error "NOTRACK rule ${rule_name}: needs src, skipping" + return 0 + } + + fw_callback pre rule + + local table=f + local chain=delegate_output + local target="${rule_target:-REJECT}" + if [ "$target" == "NOTRACK" ]; then + table=r + chain="zone_${rule_src}_notrack" + else + if [ -n "$rule_src" ]; then + if [ "$rule_src" != "*" ]; then + if [ -n "$rule_dest" ]; then + chain="zone_${rule_src}_forward" + else + chain="zone_${rule_src}_input" + fi + else + chain="${rule_dest:+delegate_forward}" + chain="${chain:-delegate_input}" + fi + fi + + if [ -n "$rule_dest" ]; then + if [ "$rule_dest" != "*" ]; then + target="zone_${rule_dest}_dest_${target}" + if [ -z "$rule_src" ]; then + chain="zone_${rule_dest}_output" + fi + elif [ "$target" = REJECT ]; then + target=reject + fi + fi + fi + + local mode + fw_get_family_mode mode ${rule_family:-x} "$rule_src" I + + local src_spec dest_spec + fw_get_negation src_spec '-s' "${rule_src_ip:+$rule_src_ip/$rule_src_ip_prefixlen}" + fw_get_negation dest_spec '-d' "${rule_dest_ip:+$rule_dest_ip/$rule_dest_ip_prefixlen}" + + [ "$rule_proto" == "tcpudp" ] && rule_proto="tcp udp" + local pr; for pr in $rule_proto; do + local sports dports itypes + case "$pr" in + icmp|icmpv6|1|58) + sports=""; dports="" + itypes="$rule_icmp_type" + ;; + *) + sports="$rule_src_port" + dports="$rule_dest_port" + itypes="" + ;; + esac + + fw_get_negation pr '-p' "$pr" + local sp; for sp in ${sports:-""}; do + fw_get_port_range sp $sp + fw_get_negation sp '--sport' "$sp" + local dp; for dp in ${dports:-""}; do + fw_get_port_range dp $dp + fw_get_negation dp '--dport' "$dp" + local sm; for sm in ${rule_src_mac:-""}; do + fw_get_negation sm '--mac-source' "$sm" + local it; for it in ${itypes:-""}; do + fw_get_negation it '--icmp-type' "$it" + fw add $mode $table $chain $target + \ + { $rule_src_ip $rule_dest_ip } { \ + $src_spec $dest_spec \ + $pr $sp $dp $it \ + ${sm:+-m mac $sm} \ + ${rule_limit:+-m limit --limit $rule_limit \ + ${rule_limit_burst:+--limit-burst $rule_limit_burst}} \ + $rule_extra \ + } + done + done + done + done + done + + fw_callback post rule +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/fw.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/fw.sh.svn-base new file mode 100644 index 0000000..ca851e8 --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/fw.sh.svn-base @@ -0,0 +1,324 @@ +# Copyright (C) 2009-2010 OpenWrt.org +# Copyright (C) 2009 Malte S. Stretz + +export FW_4_ERROR=0 +export FW_6_ERROR=0 +export FW_i_ERROR=0 +export FW_e_ERROR=0 +export FW_a_ERROR=0 + +#TODO: remove this +[ "${-#*x}" == "$-" ] && { + fw() { + fw__exec "$@" + } +} || { + fw() { + local os=$- + set +x + fw__exec "$@" + local rc=$? + set -$os + return $rc + } +} + +fw__exec() { # <action> <family> <table> <chain> <target> <position> { <rules> } + local cmd fam tab chn tgt pos + local i + for i in cmd fam tab chn tgt pos; do + if [ "$1" -a "$1" != '{' ]; then + eval "$i='$1'" + shift + else + eval "$i=-" + fi + done + + fw__rc() { + export FW_${fam#G}_ERROR=$1 + return $1 + } + + fw__dualip() { + fw $cmd 4 $tab $chn $tgt $pos "$@" + fw $cmd 6 $tab $chn $tgt $pos "$@" + fw__rc $((FW_4_ERROR | FW_6_ERROR)) + } + + fw__autoip() { + local ip4 ip6 + shift + while [ "$1" != '}' ]; do + case "$1" in + *:*) ip6=1 ;; + *.*.*.*) ip4=1 ;; + esac + shift + done + shift + if [ "${ip4:-4}" == "${ip6:-6}" ]; then + echo "fw: can't mix ip4 and ip6" >&2 + return 1 + fi + local ver=${ip4:+4}${ip6:+6} + fam=i + fw $cmd ${ver:-i} $tab $chn $tgt $pos "$@" + fw__rc $? + } + + fw__has() { + local tab=${1:-$tab} + if [ $tab == '-' ]; then + type $app > /dev/null 2> /dev/null + fw__rc $(($? & 1)) + return + fi + [ "$app" != ip6tables ] || [ "$tab" != nat ] + fw__rc $? + } + + fw__err() { + local err + eval "err=\$FW_${fam}_ERROR" + fw__rc $err + } + + local app= + local pol= + case "$fam" in + *4) [ $FW_DISABLE_IPV4 == 0 ] && app=iptables || return ;; + *6) [ $FW_DISABLE_IPV6 == 0 ] && app=ip6tables || return ;; + i) fw__dualip "$@"; return ;; + I) fw__autoip "$@"; return ;; + e) app=ebtables ;; + a) app=arptables ;; + -) fw $cmd i $tab $chn $tgt $pos "$@"; return ;; + *) return 254 ;; + esac + case "$tab" in + f) tab=filter ;; + m) tab=mangle ;; + n) tab=nat ;; + r) tab=raw ;; + -) tab=filter ;; + esac + case "$cmd:$chn:$tgt:$pos" in + add:*:-:*) cmd=new-chain ;; + add:*:*:-) cmd=append ;; + add:*:*:$) cmd=append ;; + add:*:*:*) cmd=insert ;; + del:-:*:*) cmd=delete-chain; fw flush $fam $tab ;; + del:*:-:*) cmd=delete-chain; fw flush $fam $tab $chn ;; + del:*:*:*) cmd=delete ;; + flush:*) ;; + policy:*) pol=$tgt; tgt=- ;; + has:*) fw__has; return ;; + err:*) fw__err; return ;; + list:*) cmd="numeric --verbose --$cmd" ;; + *) return 254 ;; + esac + case "$chn" in + -) chn= ;; + esac + case "$tgt" in + -) tgt= ;; + esac + + local rule_offset + case "$pos" in + ^) pos=1 ;; + $) pos= ;; + -) pos= ;; + +) eval "rule_offset=\${FW__RULE_OFS_${app}_${tab}_${chn}:-1}" ;; + esac + + if ! fw__has - family || ! fw__has $tab ; then + export FW_${fam}_ERROR=0 + return 0 + fi + + case "$fam" in + G*) shift; while [ $# -gt 0 ] && [ "$1" != "{" ]; do shift; done ;; + esac + + if [ $# -gt 0 ]; then + shift + if [ $cmd == delete ]; then + pos= + fi + fi + + local cmdline="$app --table ${tab} --${cmd} ${chn} ${pol} ${rule_offset:-${pos}} ${tgt:+--jump "$tgt"}" + while [ $# -gt 1 ]; do + # special parameter handling + case "$1:$2" in + -p:icmp*|-p:1|-p:58|--protocol:icmp*|--protocol:1|--protocol:58) + [ "$app" = ip6tables ] && \ + cmdline="$cmdline -p icmpv6" || \ + cmdline="$cmdline -p icmp" + shift + ;; + --icmp-type:*|--icmpv6-type:*) + local icmp_type + if [ "$app" = ip6tables ] && fw_check_icmptype6 icmp_type "$2"; then + cmdline="$cmdline $icmp_type" + elif [ "$app" = iptables ] && fw_check_icmptype4 icmp_type "$2"; then + cmdline="$cmdline $icmp_type" + else + local fam=IPv4; [ "$app" = ip6tables ] && fam=IPv6 + fw_log info "ICMP type '$2' is not valid for $fam address family, skipping rule" + return 1 + fi + shift + ;; + *) cmdline="$cmdline $1" ;; + esac + shift + done + + [ -n "$FW_TRACE" ] && echo $cmdline >&2 + + $cmdline + + local rv=$? + [ $rv -eq 0 ] && [ -n "$rule_offset" ] && \ + export -- "FW__RULE_OFS_${app}_${tab}_${chn}=$(($rule_offset + 1))" + fw__rc $rv +} + +fw_get_port_range() { + local _var=$1 + local _ports=$2 + local _delim=${3:-:} + if [ "$4" ]; then + fw_get_port_range $_var "${_ports}-${4}" $_delim + return + fi + + local _first=${_ports%-*} + local _last=${_ports#*-} + if [ "${_first#!}" != "${_last#!}" ]; then + export -- "$_var=$_first$_delim${_last#!}" + else + export -- "$_var=$_first" + fi +} + +fw_get_family_mode() { + local _var="$1" + local _hint="$2" + local _zone="$3" + local _mode="$4" + + local _ipv4 _ipv6 + [ "$_zone" != "*" ] && { + [ -n "$FW_ZONES4$FW_ZONES6" ] && { + list_contains FW_ZONES4 "$_zone" && _ipv4=1 || _ipv4=0 + list_contains FW_ZONES6 "$_zone" && _ipv6=1 || _ipv6=0 + } || { + _ipv4=$(uci_get_state firewall core "${_zone}_ipv4" 0) + _ipv6=$(uci_get_state firewall core "${_zone}_ipv6" 0) + } + } || { + _ipv4=1 + _ipv6=1 + } + + case "$_hint:$_ipv4:$_ipv6" in + *4:1:*|*:1:0) export -n -- "$_var=G4" ;; + *6:*:1|*:0:1) export -n -- "$_var=G6" ;; + *) export -n -- "$_var=$_mode" ;; + esac +} + +fw_get_negation() { + local _var="$1" + local _flag="$2" + local _value="$3" + + [ "${_value#!}" != "$_value" ] && \ + export -n -- "$_var=! $_flag ${_value#!}" || \ + export -n -- "$_var=${_value:+$_flag $_value}" +} + +fw_get_subnet4() { + local _var="$1" + local _flag="$2" + local _name="$3" + + local _ipaddr="$(uci_get_state network "${_name#!}" ipaddr)" + local _netmask="$(uci_get_state network "${_name#!}" netmask)" + + case "$_ipaddr" in + *.*.*.*) + [ "${_name#!}" != "$_name" ] && \ + export -n -- "$_var=! $_flag $_ipaddr/${_netmask:-255.255.255.255}" || \ + export -n -- "$_var=$_flag $_ipaddr/${_netmask:-255.255.255.255}" + return 0 + ;; + esac + + export -n -- "$_var=" + return 1 +} + +fw_check_icmptype4() { + local _var="$1" + local _type="$2" + case "$_type" in + ![0-9]*) export -n -- "$_var=! --icmp-type ${_type#!}"; return 0 ;; + [0-9]*) export -n -- "$_var=--icmp-type $_type"; return 0 ;; + esac + + [ -z "$FW_ICMP4_TYPES" ] && \ + export FW_ICMP4_TYPES=$( + iptables -p icmp -h 2>/dev/null | \ + sed -n -e '/^Valid ICMP Types:/ { + n; :r; s/[()]/ /g; s/[[:space:]]\+/\n/g; p; n; b r + }' | sort -u + ) + + local _check + for _check in $FW_ICMP4_TYPES; do + if [ "$_check" = "${_type#!}" ]; then + [ "${_type#!}" != "$_type" ] && \ + export -n -- "$_var=! --icmp-type ${_type#!}" || \ + export -n -- "$_var=--icmp-type $_type" + return 0 + fi + done + + export -n -- "$_var=" + return 1 +} + +fw_check_icmptype6() { + local _var="$1" + local _type="$2" + case "$_type" in + ![0-9]*) export -n -- "$_var=! --icmpv6-type ${_type#!}"; return 0 ;; + [0-9]*) export -n -- "$_var=--icmpv6-type $_type"; return 0 ;; + esac + + [ -z "$FW_ICMP6_TYPES" ] && \ + export FW_ICMP6_TYPES=$( + ip6tables -p icmpv6 -h 2>/dev/null | \ + sed -n -e '/^Valid ICMPv6 Types:/ { + n; :r; s/[()]/ /g; s/[[:space:]]\+/\n/g; p; n; b r + }' | sort -u + ) + + local _check + for _check in $FW_ICMP6_TYPES; do + if [ "$_check" = "${_type#!}" ]; then + [ "${_type#!}" != "$_type" ] && \ + export -n -- "$_var=! --icmpv6-type ${_type#!}" || \ + export -n -- "$_var=--icmpv6-type $_type" + return 0 + fi + done + + export -n -- "$_var=" + return 1 +} diff --git a/package/network/config/firewall/files/lib/.svn/text-base/uci_firewall.sh.svn-base b/package/network/config/firewall/files/lib/.svn/text-base/uci_firewall.sh.svn-base new file mode 100644 index 0000000..7c95a7a --- /dev/null +++ b/package/network/config/firewall/files/lib/.svn/text-base/uci_firewall.sh.svn-base @@ -0,0 +1,5 @@ +# This file is here for backwards compatibility and to override the +# uci_firewall.sh from an earlier version. +type fw_is_loaded >/dev/null || { + . /lib/firewall/core.sh +} diff --git a/package/network/config/firewall/files/lib/config.sh b/package/network/config/firewall/files/lib/config.sh new file mode 100644 index 0000000..8b2399f --- /dev/null +++ b/package/network/config/firewall/files/lib/config.sh @@ -0,0 +1,101 @@ +# Copyright (C) 2009-2010 OpenWrt.org +# Copyright (C) 2009 Malte S. Stretz <http://msquadrat.de> +# +# This is a temporary file, I hope to have some of this stuff merged into +# /lib/functions.sh (without the fw_ prefix of course) one day. + +fw_config_append() { # <package> + CONFIG_APPEND=1 config_load "$@" + unset CONFIG_APPEND +} + +fw_config_once() { # <function> <type> + local func=$1 + local type=$2 + shift 2 + + local config=cfg00nil + fw_config__once() { + config=$1 + } + config_foreach fw_config__once "$type" + + $func $config "$@" +} + +fw_config_get_section() { # <config> <prefix> <type> <name> <default> ... + local config=$1 + local prefix=$2 + shift 2 + + [ -n "$config" ] || return 1 + [ -n "$prefix" ] && { + prefix="${prefix}_" + export ${NO_EXPORT:+-n} -- "${prefix}NAME"="${config}" + config_get "${prefix}TYPE" "$config" TYPE + } + + local enabled + config_get_bool enabled "$config" enabled 1 + [ $enabled -eq 1 ] || return 1 + + [ "$1" == '{' ] && shift + while [ $# -ge 3 ]; do + local type=$1 + local name=$2 + local dflt=$3 + shift 3 + # TODO: Move handling of defaults to /lib/functions.sh + # and get replace the case block with the following + # two lines: + # type=${type#string} + # config_get${type:+_${type}} "${prefix}${name}" "$config" "$name" "$dflt" || return + case "$type" in + string) + local tmp + config_get tmp "$config" "$name" || return + [ -z "$tmp" ] && tmp=$dflt + export ${NO_EXPORT:+-n} -- "${prefix}${name}=${tmp}" + continue + ;; + boolean) + type=bool + ;; + esac; + + local cmd=${prefix}config_get_${type} + type $cmd > /dev/null || { + cmd=config_get_${type} + } + type $cmd > /dev/null || { + echo "config type $type (for $name) not supported" >&2 + return 1 + } + $cmd "${prefix}${name}" "$config" "$name" "$dflt" || return + done +} + +config_get_ipaddr() { + local varn=$1 + local conf=$2 + local name=$3 + local dflt=$4 + + local addr + config_get addr "$conf" "$name" || return + [ -n "$addr" ] || addr=$dflt + + local mask=${addr#*/} + [ "$mask" != "$addr" ] || mask= + addr=${addr%/*} + + local vers= + case "$addr" in + *:*) vers=6; mask="${mask:-128}" ;; + *.*) vers=4; mask="${mask:-32}" ;; + esac + + export ${NO_EXPORT:+-n} -- "${varn}=${addr}" + export ${NO_EXPORT:+-n} -- "${varn}_prefixlen=${mask}" + export ${NO_EXPORT:+-n} -- "${varn}_version=${vers}" +} diff --git a/package/network/config/firewall/files/lib/core.sh b/package/network/config/firewall/files/lib/core.sh new file mode 100644 index 0000000..93d4d2e --- /dev/null +++ b/package/network/config/firewall/files/lib/core.sh @@ -0,0 +1,159 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +FW_LIBDIR=${FW_LIBDIR:-/lib/firewall} + +. $FW_LIBDIR/fw.sh +include /lib/network + +fw_start() { + fw_init + + FW_DEFAULTS_APPLIED= + + fw_is_loaded && { + echo "firewall already loaded" >&2 + exit 1 + } + + uci_set_state firewall core "" firewall_state + + fw_clear DROP + + fw_callback pre core + + echo "Loading defaults" + fw_config_once fw_load_defaults defaults + + echo "Loading zones" + config_foreach fw_load_zone zone + + echo "Loading forwardings" + config_foreach fw_load_forwarding forwarding + + echo "Loading rules" + config_foreach fw_load_rule rule + + echo "Loading redirects" + config_foreach fw_load_redirect redirect + + echo "Loading includes" + config_foreach fw_load_include include + + [ -z "$FW_NOTRACK_DISABLED" ] && { + echo "Optimizing conntrack" + config_foreach fw_load_notrack_zone zone + } + + echo "Loading interfaces" + config_foreach fw_configure_interface interface add + + fw_callback post core + + uci_set_state firewall core zones "$FW_ZONES" + uci_set_state firewall core loaded 1 +} + +fw_stop() { + fw_init + + fw_callback pre stop + + local z n i + config_get z core zones + for z in $z; do + config_get n core "${z}_networks" + for n in $n; do + config_get i core "${n}_ifname" + [ -n "$i" ] && env -i ACTION=remove ZONE="$z" \ + INTERFACE="$n" DEVICE="$i" /sbin/hotplug-call firewall + done + + config_get i core "${z}_tcpmss" + [ "$i" == 1 ] && { + fw del i m FORWARD zone_${z}_MSSFIX + fw del i m zone_${z}_MSSFIX + } + done + + fw_clear ACCEPT + + fw_callback post stop + + uci_revert_state firewall + config_clear + + local h + for h in $FW_HOOKS; do unset $h; done + + unset FW_HOOKS + unset FW_INITIALIZED +} + +fw_restart() { + fw_stop + fw_start +} + +fw_reload() { + fw_restart +} + +fw_is_loaded() { + local bool=$(uci_get_state firewall.core.loaded) + return $((! ${bool:-0})) +} + + +fw_die() { + echo "Error:" "$@" >&2 + fw_log error "$@" + fw_stop + exit 1 +} + +fw_log() { + local level="$1" + [ -n "$2" ] && shift || level=notice + [ "$level" != error ] || echo "Error: $@" >&2 + logger -t firewall -p user.$level "$@" +} + + +fw_init() { + [ -z "$FW_INITIALIZED" ] || return 0 + + . $FW_LIBDIR/config.sh + + scan_interfaces + fw_config_append firewall + + local hooks="core stop defaults zone notrack synflood" + local file lib hk pp + for file in $FW_LIBDIR/core_*.sh; do + . $file + hk=$(basename $file .sh) + hk=${hk#core_} + append hooks $hk + done + for file in $FW_LIBDIR/*.sh; do + lib=$(basename $file .sh) + lib=${lib##[0-9][0-9]_} + case $lib in + core*|fw|config|uci_firewall) continue ;; + esac + . $file + for hk in $hooks; do + for pp in pre post; do + type ${lib}_${pp}_${hk}_cb >/dev/null && { + append FW_CB_${pp}_${hk} ${lib} + append FW_HOOKS FW_CB_${pp}_${hk} + } + done + done + done + + fw_callback post init + + FW_INITIALIZED=1 + return 0 +} diff --git a/package/network/config/firewall/files/lib/core_forwarding.sh b/package/network/config/firewall/files/lib/core_forwarding.sh new file mode 100644 index 0000000..2ea03f0 --- /dev/null +++ b/package/network/config/firewall/files/lib/core_forwarding.sh @@ -0,0 +1,44 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +fw_config_get_forwarding() { + [ "${forwarding_NAME}" != "$1" ] || return + fw_config_get_section "$1" forwarding { \ + string _name "$1" \ + string name "" \ + string src "" \ + string dest "" \ + string family "" \ + } || return + [ -n "$forwarding_name" ] || forwarding_name=$forwarding__name +} + +fw_load_forwarding() { + fw_config_get_forwarding "$1" + + fw_callback pre forwarding + + local chain=delegate_forward + [ -n "$forwarding_src" ] && { + chain=zone_${forwarding_src}_forward + } + + local target=ACCEPT + [ -n "$forwarding_dest" ] && { + target=zone_${forwarding_dest}_dest_ACCEPT + } + + local mode + fw_get_family_mode mode ${forwarding_family:-x} ${forwarding_dest:-${forwarding_src:--}} i + + fw add $mode f $chain $target ^ + + # propagate masq zone flag + [ -n "$forwarding_src" ] && list_contains FW_CONNTRACK_ZONES $forwarding_src && { + append FW_CONNTRACK_ZONES $forwarding_dest + } + [ -n "$forwarding_dest" ] && list_contains FW_CONNTRACK_ZONES $forwarding_dest && { + append FW_CONNTRACK_ZONES $forwarding_src + } + + fw_callback post forwarding +} diff --git a/package/network/config/firewall/files/lib/core_init.sh b/package/network/config/firewall/files/lib/core_init.sh new file mode 100644 index 0000000..404a836 --- /dev/null +++ b/package/network/config/firewall/files/lib/core_init.sh @@ -0,0 +1,361 @@ +# Copyright (C) 2009-2011 OpenWrt.org +# Copyright (C) 2008 John Crispin <blogic@openwrt.org> + +FW_INITIALIZED= + +FW_ZONES= +FW_ZONES4= +FW_ZONES6= +FW_CONNTRACK_ZONES= +FW_NOTRACK_DISABLED= + +FW_DEFAULTS_APPLIED= +FW_ADD_CUSTOM_CHAINS= +FW_ACCEPT_REDIRECTS= +FW_ACCEPT_SRC_ROUTE= + +FW_DEFAULT_INPUT_POLICY=REJECT +FW_DEFAULT_OUTPUT_POLICY=REJECT +FW_DEFAULT_FORWARD_POLICY=REJECT + +FW_DISABLE_IPV4=0 +FW_DISABLE_IPV6=0 + + +fw_load_defaults() { + fw_config_get_section "$1" defaults { \ + string input $FW_DEFAULT_INPUT_POLICY \ + string output $FW_DEFAULT_OUTPUT_POLICY \ + string forward $FW_DEFAULT_FORWARD_POLICY \ + boolean drop_invalid 0 \ + boolean syn_flood 0 \ + boolean synflood_protect 0 \ + string synflood_rate 25 \ + string synflood_burst 50 \ + boolean tcp_syncookies 1 \ + boolean tcp_ecn 0 \ + boolean tcp_westwood 0 \ + boolean tcp_window_scaling 1 \ + boolean accept_redirects 0 \ + boolean accept_source_route 0 \ + boolean custom_chains 1 \ + boolean disable_ipv6 0 \ + } || return + [ -n "$FW_DEFAULTS_APPLIED" ] && { + fw_log error "duplicate defaults section detected, skipping" + return 1 + } + FW_DEFAULTS_APPLIED=1 + + FW_DEFAULT_INPUT_POLICY=$defaults_input + FW_DEFAULT_OUTPUT_POLICY=$defaults_output + FW_DEFAULT_FORWARD_POLICY=$defaults_forward + + FW_ADD_CUSTOM_CHAINS=$defaults_custom_chains + + FW_ACCEPT_REDIRECTS=$defaults_accept_redirects + FW_ACCEPT_SRC_ROUTE=$defaults_accept_source_route + + FW_DISABLE_IPV6=$defaults_disable_ipv6 + + fw_callback pre defaults + + # Seems like there are only one sysctl for both IP versions. + for s in syncookies ecn westwood window_scaling; do + eval "sysctl -e -w net.ipv4.tcp_${s}=\$defaults_tcp_${s}" >/dev/null + done + fw_sysctl_interface all + + fw add i f INPUT ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED } + fw add i f OUTPUT ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED } + fw add i f FORWARD ACCEPT { -m conntrack --ctstate RELATED,ESTABLISHED } + + [ $defaults_drop_invalid == 1 ] && { + fw add i f INPUT DROP { -m conntrack --ctstate INVALID } + fw add i f OUTPUT DROP { -m conntrack --ctstate INVALID } + fw add i f FORWARD DROP { -m conntrack --ctstate INVALID } + FW_NOTRACK_DISABLED=1 + } + + fw add i f INPUT ACCEPT { -i lo } + fw add i f OUTPUT ACCEPT { -o lo } + + # Compatibility to old 'syn_flood' parameter + [ $defaults_syn_flood == 1 ] && \ + defaults_synflood_protect=1 + + [ "${defaults_synflood_rate%/*}" == "$defaults_synflood_rate" ] && \ + defaults_synflood_rate="$defaults_synflood_rate/second" + + [ $defaults_synflood_protect == 1 ] && { + echo "Loading synflood protection" + fw_callback pre synflood + fw add i f syn_flood + fw add i f syn_flood RETURN { \ + -p tcp --syn \ + -m limit --limit "${defaults_synflood_rate}" --limit-burst "${defaults_synflood_burst}" \ + } + fw add i f syn_flood DROP + fw add i f INPUT syn_flood { -p tcp --syn } + fw_callback post synflood + } + + [ $defaults_custom_chains == 1 ] && { + echo "Adding custom chains" + fw add i f input_rule + fw add i f output_rule + fw add i f forwarding_rule + fw add i n prerouting_rule + fw add i n postrouting_rule + + fw add i f INPUT input_rule + fw add i f OUTPUT output_rule + fw add i f FORWARD forwarding_rule + fw add i n PREROUTING prerouting_rule + fw add i n POSTROUTING postrouting_rule + } + + fw add i f delegate_input + fw add i f delegate_output + fw add i f delegate_forward + + fw add i f INPUT delegate_input + fw add i f OUTPUT delegate_output + fw add i f FORWARD delegate_forward + + fw add i f reject + fw add i f reject REJECT { --reject-with tcp-reset -p tcp } + fw add i f reject REJECT { --reject-with port-unreach } + + fw_set_filter_policy + + fw_callback post defaults +} + + +fw_config_get_zone() { + [ "${zone_NAME}" != "$1" ] || return + fw_config_get_section "$1" zone { \ + string name "$1" \ + string network "" \ + string device "" \ + string subnet "" \ + string input "$FW_DEFAULT_INPUT_POLICY" \ + string output "$FW_DEFAULT_OUTPUT_POLICY" \ + string forward "$FW_DEFAULT_FORWARD_POLICY" \ + boolean masq 0 \ + string masq_src "" \ + string masq_dest "" \ + string extra "" \ + string extra_src "" \ + string extra_dest "" \ + boolean conntrack 0 \ + boolean mtu_fix 0 \ + boolean custom_chains 0 \ + boolean log 0 \ + string log_limit 10 \ + string family "" \ + } || return + [ -n "$zone_name" ] || zone_name=$zone_NAME + [ -n "$zone_extra_src" ] || zone_extra_src="$zone_extra" + [ -n "$zone_extra_dest" ] || zone_extra_dest="$zone_extra" + [ -n "$zone_network$zone_subnet$zone_device$zone_extra_src$zone_extra_dest" ] || zone_network=$zone_name +} + +fw_load_zone() { + fw_config_get_zone "$1" + + list_contains FW_ZONES $zone_name && { + fw_log error "zone ${zone_name}: duplicated zone, skipping" + return 0 + } + append FW_ZONES $zone_name + + fw_callback pre zone + + [ $zone_conntrack = 1 -o $zone_masq = 1 ] && \ + append FW_CONNTRACK_ZONES "$zone_name" + + local mode + case "$zone_family" in + *4) + mode=4 + append FW_ZONES4 $zone_name + uci_set_state firewall core ${zone_name}_ipv4 1 + ;; + *6) + mode=6 + append FW_ZONES6 $zone_name + uci_set_state firewall core ${zone_name}_ipv6 1 + ;; + *) + mode=i + append FW_ZONES4 $zone_name + append FW_ZONES6 $zone_name + uci_set_state firewall core ${zone_name}_ipv4 1 + uci_set_state firewall core ${zone_name}_ipv6 1 + ;; + esac + + local chain=zone_${zone_name} + + fw add $mode f ${chain}_src_ACCEPT + fw add $mode f ${chain}_src_DROP + fw add $mode f ${chain}_src_REJECT + + fw add $mode f ${chain}_dest_ACCEPT + fw add $mode f ${chain}_dest_DROP + fw add $mode f ${chain}_dest_REJECT + + fw add $mode f ${chain}_input + fw add $mode f ${chain}_input ${chain}_src_${zone_input} $ + + fw add $mode f ${chain}_forward + fw add $mode f ${chain}_forward ${chain}_dest_${zone_forward} $ + + fw add $mode f ${chain}_output + fw add $mode f ${chain}_output ${chain}_dest_${zone_output} $ + + # TODO: Rename to ${chain}_MASQUERADE + fw add $mode n ${chain}_nat + fw add $mode n ${chain}_prerouting + + fw add $mode r ${chain}_notrack + + [ $zone_mtu_fix == 1 ] && { + fw add $mode m ${chain}_MSSFIX + fw add $mode m FORWARD ${chain}_MSSFIX ^ + uci_set_state firewall core ${zone_name}_tcpmss 1 + } + + [ $zone_custom_chains == 1 ] && { + [ $FW_ADD_CUSTOM_CHAINS == 1 ] || \ + fw_die "zone ${zone_name}: custom_chains globally disabled" + + fw add $mode f input_${zone_name} + fw add $mode f ${chain}_input input_${zone_name} ^ + + fw add $mode f forwarding_${zone_name} + fw add $mode f ${chain}_forward forwarding_${zone_name} ^ + + fw add $mode n prerouting_${zone_name} + fw add $mode n ${chain}_prerouting prerouting_${zone_name} ^ + } + + [ "$zone_log" == 1 ] && { + [ "${zone_log_limit%/*}" == "$zone_log_limit" ] && \ + zone_log_limit="$zone_log_limit/minute" + + local t + for t in REJECT DROP; do + local d + for d in src dest; do + fw add $mode f ${chain}_${d}_${t} LOG ^ \ + { -m limit --limit $zone_log_limit --log-prefix "$t($d:$zone_name): " } + done + done + + [ $zone_mtu_fix == 1 ] && \ + fw add $mode m ${chain}_MSSFIX LOG ^ \ + { -p tcp --tcp-flags SYN,RST SYN -m limit --limit $zone_log_limit --log-prefix "MSSFIX($zone_name): " } + } + + # NB: if MASQUERADING for IPv6 becomes available we'll need a family check here + if [ "$zone_masq" == 1 ]; then + local msrc mdst + for msrc in ${zone_masq_src:-0.0.0.0/0}; do + case "$msrc" in + *.*) fw_get_negation msrc '-s' "$msrc" ;; + *) fw_get_subnet4 msrc '-s' "$msrc" || break ;; + esac + + for mdst in ${zone_masq_dest:-0.0.0.0/0}; do + case "$mdst" in + *.*) fw_get_negation mdst '-d' "$mdst" ;; + *) fw_get_subnet4 mdst '-d' "$mdst" || break ;; + esac + + fw add $mode n ${chain}_nat MASQUERADE $ { $msrc $mdst } + done + done + fi + + local dev + for dev in ${zone_device:-""}; do + local net + for net in ${zone_subnet:-""}; do + [ -n "$dev" ] || [ -n "$net" ] || continue + fw_do_interface_rules add "${zone_name}" "$dev" "$net" \ + "${zone_extra_src}" "${zone_extra_dest}" + done + done + + fw_callback post zone +} + +fw_load_notrack_zone() { + fw_config_get_zone "$1" + list_contains FW_CONNTRACK_ZONES "${zone_name}" && return + + fw_callback pre notrack + + fw add i r zone_${zone_name}_notrack NOTRACK $ + + fw_callback post notrack +} + + +fw_load_include() { + local name="$1" + + local path + config_get path ${name} path + + [ -e $path ] && ( + config() { + fw_log error "You cannot use UCI in firewall includes!" >&2 + exit 1 + } + . $path + ) +} + + +fw_clear() { + local policy=$1 + + fw_set_filter_policy $policy + + local tab + for tab in f n r; do + fw del i $tab + done +} + +fw_set_filter_policy() { + local policy=$1 + + local chn tgt + for chn in INPUT OUTPUT FORWARD; do + eval "tgt=\${policy:-\${FW_DEFAULT_${chn}_POLICY}}" + [ $tgt == "REJECT" ] && tgt=reject + [ $tgt == "ACCEPT" -o $tgt == "DROP" ] || { + fw add i f $chn $tgt $ + tgt=DROP + } + fw policy i f $chn $tgt + done +} + + +fw_callback() { + local pp=$1 + local hk=$2 + + local libs lib + eval "libs=\$FW_CB_${pp}_${hk}" + [ -n "$libs" ] || return + for lib in $libs; do + ${lib}_${pp}_${hk}_cb + done +} diff --git a/package/network/config/firewall/files/lib/core_interface.sh b/package/network/config/firewall/files/lib/core_interface.sh new file mode 100644 index 0000000..9138cbf --- /dev/null +++ b/package/network/config/firewall/files/lib/core_interface.sh @@ -0,0 +1,214 @@ +# Copyright (C) 2009-2013 OpenWrt.org + +fw__uci_state_add() { + local var="$1" + local item="$2" + + local val="$(uci_get_state firewall core $var)" + local e1; for e1 in $item; do + local e2; for e2 in $val; do + [ "$e1" = "$e2" ] && e1="" + done + val="${val:+$val${e1:+ }}$e1" + done + + uci_toggle_state firewall core $var "$val" +} + +fw__uci_state_del() { + local var="$1" + local item="$2" + + local rest="" + local val="$(uci_get_state firewall core $var)" + local e1; for e1 in $val; do + local e2; for e2 in $item; do + [ "$e1" = "$e2" ] && e1="" + done + rest="${rest:+$rest${e1:+ }}$e1" + done + + uci_toggle_state firewall core $var "$rest" +} + +fw_do_interface_rules() { + local action=$1 + local zone=$2 + local chain=zone_${zone} + local ifname=$3 + local subnet=$4 + local extra_src="$5" + local extra_dest="$6" + + local idev odev inet onet mode + fw_get_family_mode mode x $zone i + + fw_get_negation idev '-i' "$ifname" + fw_get_negation odev '-o' "$ifname" + + case "$mode/$subnet" in + # Zone supports v6 only or dual, need v6 + G6/*:*|i/*:*) + fw_get_negation inet '-s' "$subnet" + fw_get_negation onet '-d' "$subnet" + mode=6 + ;; + + # Zone supports v4 only or dual, need v4 + G4/*.*.*.*|i/*.*.*.*) + fw_get_negation inet '-s' "$subnet" + fw_get_negation onet '-d' "$subnet" + mode=4 + ;; + + # Need v6 while zone is v4 + */*:*) fw_log info "zone $zone does not support IPv6 address family, skipping"; return ;; + + # Need v4 while zone is v6 + */*.*) fw_log info "zone $zone does not support IPv4 address family, skipping"; return ;; + + # Strip prefix + *) mode="${mode#G}" ;; + esac + + lock /var/run/firewall-interface.lock + + fw $action $mode f ${chain}_dest_ACCEPT ACCEPT $ { $odev $onet $extra_dest } + fw $action $mode f ${chain}_src_ACCEPT ACCEPT $ { $idev $inet $extra_src } + fw $action $mode f ${chain}_dest_DROP DROP $ { $odev $onet $extra_dest } + fw $action $mode f ${chain}_src_DROP DROP $ { $idev $inet $extra_src } + fw $action $mode f ${chain}_dest_REJECT reject $ { $odev $onet $extra_dest } + fw $action $mode f ${chain}_src_REJECT reject $ { $idev $inet $extra_src } + + [ "$(uci_get_state firewall core "${zone}_tcpmss")" == 1 ] && \ + fw $action $mode m ${chain}_MSSFIX TCPMSS $ \ + { $odev -p tcp --tcp-flags SYN,RST SYN --clamp-mss-to-pmtu $onet $extra_dest } + + fw $action $mode f delegate_input ${chain}_input $ { $idev $inet $extra_src } + fw $action $mode f delegate_forward ${chain}_forward $ { $idev $inet $extra_src } + fw $action $mode f delegate_output ${chain}_output $ { $odev $onet $extra_dest } + + fw $action $mode n PREROUTING ${chain}_prerouting $ { $idev $inet $extra_src } + fw $action $mode r PREROUTING ${chain}_notrack $ { $idev $inet $extra_src } + fw $action $mode n POSTROUTING ${chain}_nat $ { $odev $onet $extra_dest } + + # Flush conntrack table + echo f >/proc/net/nf_conntrack 2>/dev/null + + lock -u /var/run/firewall-interface.lock +} + +fw_configure_interface() { + local iface=$1 + local action=$2 + local ifname=$3 + local aliasnet=$4 + + [ "$action" == "add" ] && { + local status=$(uci_get_state network "$iface" up 0) + [ "$status" == 1 ] || [ -n "$aliasnet" ] || return 0 + } + + [ -n "$ifname" ] || { + ifname=$(uci_get_state network "$iface" ifname) + ifname="${ifname%%:*}" + [ -z "$ifname" ] && return 0 + } + + [ "$ifname" == "lo" ] && return 0 + + fw_callback pre interface + + local old_zones old_ifname old_subnets + config_get old_zones core "${iface}_zone" + [ -n "$old_zones" ] && { + config_get old_ifname core "${iface}_ifname" + config_get old_subnets core "${iface}_subnets" + + local z + for z in $old_zones; do + local n + for n in ${old_subnets:-""}; do + fw_log info "removing $iface ($old_ifname${n:+ alias $n}) from zone $z" + fw_do_interface_rules del $z $old_ifname $n + done + + [ -n "$old_subnets" ] || { + fw__uci_state_del "${z}_networks" "$iface" + env -i ACTION=remove ZONE="$z" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall + } + done + + local old_aliases + config_get old_aliases core "${iface}_aliases" + + local a + for a in $old_aliases; do + fw_configure_interface "$a" del "$old_ifname" + done + + uci_revert_state firewall core "${iface}_zone" + uci_revert_state firewall core "${iface}_ifname" + uci_revert_state firewall core "${iface}_subnets" + uci_revert_state firewall core "${iface}_aliases" + } + + [ "$action" == del ] && return + + [ -z "$aliasnet" ] && { + local aliases + config_get aliases "$iface" aliases + + local a + for a in $aliases; do + local ipaddr netmask ip6addr + config_get ipaddr "$a" ipaddr + config_get netmask "$a" netmask + config_get ip6addr "$a" ip6addr + + [ -n "$ipaddr" ] && fw_configure_interface "$a" add "" "$ipaddr${netmask:+/$netmask}" + [ -n "$ip6addr" ] && fw_configure_interface "$a" add "" "$ip6addr" + done + + fw_sysctl_interface $ifname + fw_callback post interface + + uci_toggle_state firewall core "${iface}_aliases" "$aliases" + } || { + local subnets= + config_get subnets core "${iface}_subnets" + append subnets "$aliasnet" + + config_set core "${iface}_subnets" "$subnets" + uci_toggle_state firewall core "${iface}_subnets" "$subnets" + } + + local new_zones= + load_zone() { + fw_config_get_zone "$1" + list_contains zone_network "$iface" || return + + fw_log info "adding $iface ($ifname${aliasnet:+ alias $aliasnet}) to zone $zone_name" + fw_do_interface_rules add ${zone_name} "$ifname" "$aliasnet" + append new_zones $zone_name + + [ -n "$aliasnet" ] || { + fw__uci_state_add "${zone_name}_networks" "${zone_network}" + env -i ACTION=add ZONE="$zone_name" INTERFACE="$iface" DEVICE="$ifname" /sbin/hotplug-call firewall + } + } + config_foreach load_zone zone + + uci_toggle_state firewall core "${iface}_zone" "$new_zones" + uci_toggle_state firewall core "${iface}_ifname" "$ifname" +} + +fw_sysctl_interface() { + local ifname=$1 + { + sysctl -w net.ipv4.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS + sysctl -w net.ipv6.conf.${ifname}.accept_redirects=$FW_ACCEPT_REDIRECTS + sysctl -w net.ipv4.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE + sysctl -w net.ipv6.conf.${ifname}.accept_source_route=$FW_ACCEPT_SRC_ROUTE + } >/dev/null 2>/dev/null +} diff --git a/package/network/config/firewall/files/lib/core_redirect.sh b/package/network/config/firewall/files/lib/core_redirect.sh new file mode 100644 index 0000000..9493bc6 --- /dev/null +++ b/package/network/config/firewall/files/lib/core_redirect.sh @@ -0,0 +1,130 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +fw_config_get_redirect() { + [ "${redirect_NAME}" != "$1" ] || return + fw_config_get_section "$1" redirect { \ + string _name "$1" \ + string name "" \ + string src "" \ + ipaddr src_ip "" \ + ipaddr src_dip "" \ + string src_mac "" \ + string src_port "" \ + string src_dport "" \ + string dest "" \ + ipaddr dest_ip "" \ + string dest_port "" \ + string proto "tcpudp" \ + string family "" \ + string target "DNAT" \ + string extra "" \ + } || return + [ -n "$redirect_name" ] || redirect_name=$redirect__name +} + +fw_load_redirect() { + fw_config_get_redirect "$1" + + fw_callback pre redirect + + local fwdchain natchain natopt nataddr natports srcdaddr srcdports + if [ "$redirect_target" == "DNAT" ]; then + [ -n "${redirect_src#*}" -a -n "$redirect_dest_ip$redirect_dest_port" ] || { + fw_log error "DNAT redirect ${redirect_name}: needs src and dest_ip or dest_port, skipping" + return 0 + } + + fwdopt="" + fwdchain="" + + # Check whether only ports are given or whether the given dest ip is local, + # in this case match only DNATed traffic and allow it on input, not forward + if [ -z "$redirect_dest_ip" ] || /sbin/ifconfig | grep -qE "addr:${redirect_dest_ip//./\\.}\b"; then + fwdopt="-m conntrack --ctstate DNAT" + fwdchain="zone_${redirect_src}_input" + else + fwdchain="zone_${redirect_src}_forward" + fi + + natopt="--to-destination" + natchain="zone_${redirect_src}_prerouting" + nataddr="$redirect_dest_ip" + fw_get_port_range natports "${redirect_dest_port#!}" "-" + + fw_get_negation srcdaddr '-d' "${redirect_src_dip:+$redirect_src_dip/$redirect_src_dip_prefixlen}" + fw_get_port_range srcdports "$redirect_src_dport" ":" + fw_get_negation srcdports '--dport' "$srcdports" + + list_contains FW_CONNTRACK_ZONES $redirect_src || \ + append FW_CONNTRACK_ZONES $redirect_src + + elif [ "$redirect_target" == "SNAT" ]; then + [ -n "${redirect_dest#*}" -a -n "$redirect_src_dip" ] || { + fw_log error "SNAT redirect ${redirect_name}: needs dest and src_dip, skipping" + return 0 + } + + fwdchain="${redirect_src:+zone_${redirect_src}_forward}" + + natopt="--to-source" + natchain="zone_${redirect_dest}_nat" + nataddr="$redirect_src_dip" + fw_get_port_range natports "${redirect_src_dport#!}" "-" + + fw_get_negation srcdaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" + fw_get_port_range srcdports "$redirect_dest_port" ":" + fw_get_negation srcdports '--dport' "$srcdports" + + list_contains FW_CONNTRACK_ZONES $redirect_dest || \ + append FW_CONNTRACK_ZONES $redirect_dest + + else + fw_log error "redirect ${redirect_name}: target must be either DNAT or SNAT, skipping" + return 0 + fi + + local mode + fw_get_family_mode mode ${redirect_family:-x} ${redirect_src:-$redirect_dest} I + + local srcaddr + fw_get_negation srcaddr '-s' "${redirect_src_ip:+$redirect_src_ip/$redirect_src_ip_prefixlen}" + + local srcports + fw_get_port_range srcports "$redirect_src_port" ":" + fw_get_negation srcports '--sport' "$srcports" + + local destaddr + fw_get_negation destaddr '-d' "${redirect_dest_ip:+$redirect_dest_ip/$redirect_dest_ip_prefixlen}" + + local destports + fw_get_port_range destports "${redirect_dest_port:-$redirect_src_dport}" ":" + fw_get_negation destports '--dport' "$destports" + + [ "$redirect_proto" == "tcpudp" ] && redirect_proto="tcp udp" + local pr; for pr in $redirect_proto; do + fw_get_negation pr '-p' "$pr" + local sm; for sm in ${redirect_src_mac:-""}; do + fw_get_negation sm '--mac-source' "$sm" + fw add $mode n $natchain $redirect_target + \ + { $redirect_src_ip $redirect_dest_ip } { \ + $srcaddr $srcdaddr $pr \ + $srcports $srcdports \ + ${sm:+-m mac $sm} \ + $natopt $nataddr${natports:+:$natports} \ + $redirect_options \ + } + + fw add $mode f ${fwdchain:-delegate_forward} ACCEPT + \ + { $redirect_src_ip $redirect_dest_ip } { \ + $srcaddr $destaddr \ + $pr \ + $srcports $destports \ + ${sm:+-m mac $sm} \ + $fwdopt \ + $redirect_extra \ + } + done + done + + fw_callback post redirect +} diff --git a/package/network/config/firewall/files/lib/core_rule.sh b/package/network/config/firewall/files/lib/core_rule.sh new file mode 100644 index 0000000..0ce2122 --- /dev/null +++ b/package/network/config/firewall/files/lib/core_rule.sh @@ -0,0 +1,117 @@ +# Copyright (C) 2009-2010 OpenWrt.org + +fw_config_get_rule() { + [ "${rule_NAME}" != "$1" ] || return + fw_config_get_section "$1" rule { \ + string _name "$1" \ + string name "" \ + string src "" \ + ipaddr src_ip "" \ + string src_mac "" \ + string src_port "" \ + string dest "" \ + ipaddr dest_ip "" \ + string dest_port "" \ + string icmp_type "" \ + string proto "tcpudp" \ + string target "" \ + string family "" \ + string limit "" \ + string limit_burst "" \ + string extra "" \ + } || return + [ -n "$rule_name" ] || rule_name=$rule__name +} + +fw_load_rule() { + fw_config_get_rule "$1" + + [ "$rule_target" != "NOTRACK" ] || [ -n "$rule_src" ] || [ "$rule_src" != "*" ] || { + fw_log error "NOTRACK rule ${rule_name}: needs src, skipping" + return 0 + } + + fw_callback pre rule + + local table=f + local chain=delegate_output + local target="${rule_target:-REJECT}" + if [ "$target" == "NOTRACK" ]; then + table=r + chain="zone_${rule_src}_notrack" + else + if [ -n "$rule_src" ]; then + if [ "$rule_src" != "*" ]; then + if [ -n "$rule_dest" ]; then + chain="zone_${rule_src}_forward" + else + chain="zone_${rule_src}_input" + fi + else + chain="${rule_dest:+delegate_forward}" + chain="${chain:-delegate_input}" + fi + fi + + if [ -n "$rule_dest" ]; then + if [ "$rule_dest" != "*" ]; then + target="zone_${rule_dest}_dest_${target}" + if [ -z "$rule_src" ]; then + chain="zone_${rule_dest}_output" + fi + elif [ "$target" = REJECT ]; then + target=reject + fi + fi + fi + + local mode + fw_get_family_mode mode ${rule_family:-x} "$rule_src" I + + local src_spec dest_spec + fw_get_negation src_spec '-s' "${rule_src_ip:+$rule_src_ip/$rule_src_ip_prefixlen}" + fw_get_negation dest_spec '-d' "${rule_dest_ip:+$rule_dest_ip/$rule_dest_ip_prefixlen}" + + [ "$rule_proto" == "tcpudp" ] && rule_proto="tcp udp" + local pr; for pr in $rule_proto; do + local sports dports itypes + case "$pr" in + icmp|icmpv6|1|58) + sports=""; dports="" + itypes="$rule_icmp_type" + ;; + *) + sports="$rule_src_port" + dports="$rule_dest_port" + itypes="" + ;; + esac + + fw_get_negation pr '-p' "$pr" + local sp; for sp in ${sports:-""}; do + fw_get_port_range sp $sp + fw_get_negation sp '--sport' "$sp" + local dp; for dp in ${dports:-""}; do + fw_get_port_range dp $dp + fw_get_negation dp '--dport' "$dp" + local sm; for sm in ${rule_src_mac:-""}; do + fw_get_negation sm '--mac-source' "$sm" + local it; for it in ${itypes:-""}; do + fw_get_negation it '--icmp-type' "$it" + fw add $mode $table $chain $target + \ + { $rule_src_ip $rule_dest_ip } { \ + $src_spec $dest_spec \ + $pr $sp $dp $it \ + ${sm:+-m mac $sm} \ + ${rule_limit:+-m limit --limit $rule_limit \ + ${rule_limit_burst:+--limit-burst $rule_limit_burst}} \ + $rule_extra \ + } + done + done + done + done + done + + fw_callback post rule +} diff --git a/package/network/config/firewall/files/lib/fw.sh b/package/network/config/firewall/files/lib/fw.sh new file mode 100644 index 0000000..ca851e8 --- /dev/null +++ b/package/network/config/firewall/files/lib/fw.sh @@ -0,0 +1,324 @@ +# Copyright (C) 2009-2010 OpenWrt.org +# Copyright (C) 2009 Malte S. Stretz + +export FW_4_ERROR=0 +export FW_6_ERROR=0 +export FW_i_ERROR=0 +export FW_e_ERROR=0 +export FW_a_ERROR=0 + +#TODO: remove this +[ "${-#*x}" == "$-" ] && { + fw() { + fw__exec "$@" + } +} || { + fw() { + local os=$- + set +x + fw__exec "$@" + local rc=$? + set -$os + return $rc + } +} + +fw__exec() { # <action> <family> <table> <chain> <target> <position> { <rules> } + local cmd fam tab chn tgt pos + local i + for i in cmd fam tab chn tgt pos; do + if [ "$1" -a "$1" != '{' ]; then + eval "$i='$1'" + shift + else + eval "$i=-" + fi + done + + fw__rc() { + export FW_${fam#G}_ERROR=$1 + return $1 + } + + fw__dualip() { + fw $cmd 4 $tab $chn $tgt $pos "$@" + fw $cmd 6 $tab $chn $tgt $pos "$@" + fw__rc $((FW_4_ERROR | FW_6_ERROR)) + } + + fw__autoip() { + local ip4 ip6 + shift + while [ "$1" != '}' ]; do + case "$1" in + *:*) ip6=1 ;; + *.*.*.*) ip4=1 ;; + esac + shift + done + shift + if [ "${ip4:-4}" == "${ip6:-6}" ]; then + echo "fw: can't mix ip4 and ip6" >&2 + return 1 + fi + local ver=${ip4:+4}${ip6:+6} + fam=i + fw $cmd ${ver:-i} $tab $chn $tgt $pos "$@" + fw__rc $? + } + + fw__has() { + local tab=${1:-$tab} + if [ $tab == '-' ]; then + type $app > /dev/null 2> /dev/null + fw__rc $(($? & 1)) + return + fi + [ "$app" != ip6tables ] || [ "$tab" != nat ] + fw__rc $? + } + + fw__err() { + local err + eval "err=\$FW_${fam}_ERROR" + fw__rc $err + } + + local app= + local pol= + case "$fam" in + *4) [ $FW_DISABLE_IPV4 == 0 ] && app=iptables || return ;; + *6) [ $FW_DISABLE_IPV6 == 0 ] && app=ip6tables || return ;; + i) fw__dualip "$@"; return ;; + I) fw__autoip "$@"; return ;; + e) app=ebtables ;; + a) app=arptables ;; + -) fw $cmd i $tab $chn $tgt $pos "$@"; return ;; + *) return 254 ;; + esac + case "$tab" in + f) tab=filter ;; + m) tab=mangle ;; + n) tab=nat ;; + r) tab=raw ;; + -) tab=filter ;; + esac + case "$cmd:$chn:$tgt:$pos" in + add:*:-:*) cmd=new-chain ;; + add:*:*:-) cmd=append ;; + add:*:*:$) cmd=append ;; + add:*:*:*) cmd=insert ;; + del:-:*:*) cmd=delete-chain; fw flush $fam $tab ;; + del:*:-:*) cmd=delete-chain; fw flush $fam $tab $chn ;; + del:*:*:*) cmd=delete ;; + flush:*) ;; + policy:*) pol=$tgt; tgt=- ;; + has:*) fw__has; return ;; + err:*) fw__err; return ;; + list:*) cmd="numeric --verbose --$cmd" ;; + *) return 254 ;; + esac + case "$chn" in + -) chn= ;; + esac + case "$tgt" in + -) tgt= ;; + esac + + local rule_offset + case "$pos" in + ^) pos=1 ;; + $) pos= ;; + -) pos= ;; + +) eval "rule_offset=\${FW__RULE_OFS_${app}_${tab}_${chn}:-1}" ;; + esac + + if ! fw__has - family || ! fw__has $tab ; then + export FW_${fam}_ERROR=0 + return 0 + fi + + case "$fam" in + G*) shift; while [ $# -gt 0 ] && [ "$1" != "{" ]; do shift; done ;; + esac + + if [ $# -gt 0 ]; then + shift + if [ $cmd == delete ]; then + pos= + fi + fi + + local cmdline="$app --table ${tab} --${cmd} ${chn} ${pol} ${rule_offset:-${pos}} ${tgt:+--jump "$tgt"}" + while [ $# -gt 1 ]; do + # special parameter handling + case "$1:$2" in + -p:icmp*|-p:1|-p:58|--protocol:icmp*|--protocol:1|--protocol:58) + [ "$app" = ip6tables ] && \ + cmdline="$cmdline -p icmpv6" || \ + cmdline="$cmdline -p icmp" + shift + ;; + --icmp-type:*|--icmpv6-type:*) + local icmp_type + if [ "$app" = ip6tables ] && fw_check_icmptype6 icmp_type "$2"; then + cmdline="$cmdline $icmp_type" + elif [ "$app" = iptables ] && fw_check_icmptype4 icmp_type "$2"; then + cmdline="$cmdline $icmp_type" + else + local fam=IPv4; [ "$app" = ip6tables ] && fam=IPv6 + fw_log info "ICMP type '$2' is not valid for $fam address family, skipping rule" + return 1 + fi + shift + ;; + *) cmdline="$cmdline $1" ;; + esac + shift + done + + [ -n "$FW_TRACE" ] && echo $cmdline >&2 + + $cmdline + + local rv=$? + [ $rv -eq 0 ] && [ -n "$rule_offset" ] && \ + export -- "FW__RULE_OFS_${app}_${tab}_${chn}=$(($rule_offset + 1))" + fw__rc $rv +} + +fw_get_port_range() { + local _var=$1 + local _ports=$2 + local _delim=${3:-:} + if [ "$4" ]; then + fw_get_port_range $_var "${_ports}-${4}" $_delim + return + fi + + local _first=${_ports%-*} + local _last=${_ports#*-} + if [ "${_first#!}" != "${_last#!}" ]; then + export -- "$_var=$_first$_delim${_last#!}" + else + export -- "$_var=$_first" + fi +} + +fw_get_family_mode() { + local _var="$1" + local _hint="$2" + local _zone="$3" + local _mode="$4" + + local _ipv4 _ipv6 + [ "$_zone" != "*" ] && { + [ -n "$FW_ZONES4$FW_ZONES6" ] && { + list_contains FW_ZONES4 "$_zone" && _ipv4=1 || _ipv4=0 + list_contains FW_ZONES6 "$_zone" && _ipv6=1 || _ipv6=0 + } || { + _ipv4=$(uci_get_state firewall core "${_zone}_ipv4" 0) + _ipv6=$(uci_get_state firewall core "${_zone}_ipv6" 0) + } + } || { + _ipv4=1 + _ipv6=1 + } + + case "$_hint:$_ipv4:$_ipv6" in + *4:1:*|*:1:0) export -n -- "$_var=G4" ;; + *6:*:1|*:0:1) export -n -- "$_var=G6" ;; + *) export -n -- "$_var=$_mode" ;; + esac +} + +fw_get_negation() { + local _var="$1" + local _flag="$2" + local _value="$3" + + [ "${_value#!}" != "$_value" ] && \ + export -n -- "$_var=! $_flag ${_value#!}" || \ + export -n -- "$_var=${_value:+$_flag $_value}" +} + +fw_get_subnet4() { + local _var="$1" + local _flag="$2" + local _name="$3" + + local _ipaddr="$(uci_get_state network "${_name#!}" ipaddr)" + local _netmask="$(uci_get_state network "${_name#!}" netmask)" + + case "$_ipaddr" in + *.*.*.*) + [ "${_name#!}" != "$_name" ] && \ + export -n -- "$_var=! $_flag $_ipaddr/${_netmask:-255.255.255.255}" || \ + export -n -- "$_var=$_flag $_ipaddr/${_netmask:-255.255.255.255}" + return 0 + ;; + esac + + export -n -- "$_var=" + return 1 +} + +fw_check_icmptype4() { + local _var="$1" + local _type="$2" + case "$_type" in + ![0-9]*) export -n -- "$_var=! --icmp-type ${_type#!}"; return 0 ;; + [0-9]*) export -n -- "$_var=--icmp-type $_type"; return 0 ;; + esac + + [ -z "$FW_ICMP4_TYPES" ] && \ + export FW_ICMP4_TYPES=$( + iptables -p icmp -h 2>/dev/null | \ + sed -n -e '/^Valid ICMP Types:/ { + n; :r; s/[()]/ /g; s/[[:space:]]\+/\n/g; p; n; b r + }' | sort -u + ) + + local _check + for _check in $FW_ICMP4_TYPES; do + if [ "$_check" = "${_type#!}" ]; then + [ "${_type#!}" != "$_type" ] && \ + export -n -- "$_var=! --icmp-type ${_type#!}" || \ + export -n -- "$_var=--icmp-type $_type" + return 0 + fi + done + + export -n -- "$_var=" + return 1 +} + +fw_check_icmptype6() { + local _var="$1" + local _type="$2" + case "$_type" in + ![0-9]*) export -n -- "$_var=! --icmpv6-type ${_type#!}"; return 0 ;; + [0-9]*) export -n -- "$_var=--icmpv6-type $_type"; return 0 ;; + esac + + [ -z "$FW_ICMP6_TYPES" ] && \ + export FW_ICMP6_TYPES=$( + ip6tables -p icmpv6 -h 2>/dev/null | \ + sed -n -e '/^Valid ICMPv6 Types:/ { + n; :r; s/[()]/ /g; s/[[:space:]]\+/\n/g; p; n; b r + }' | sort -u + ) + + local _check + for _check in $FW_ICMP6_TYPES; do + if [ "$_check" = "${_type#!}" ]; then + [ "${_type#!}" != "$_type" ] && \ + export -n -- "$_var=! --icmpv6-type ${_type#!}" || \ + export -n -- "$_var=--icmpv6-type $_type" + return 0 + fi + done + + export -n -- "$_var=" + return 1 +} diff --git a/package/network/config/firewall/files/lib/uci_firewall.sh b/package/network/config/firewall/files/lib/uci_firewall.sh new file mode 100644 index 0000000..7c95a7a --- /dev/null +++ b/package/network/config/firewall/files/lib/uci_firewall.sh @@ -0,0 +1,5 @@ +# This file is here for backwards compatibility and to override the +# uci_firewall.sh from an earlier version. +type fw_is_loaded >/dev/null || { + . /lib/firewall/core.sh +} diff --git a/package/network/config/firewall/files/reflection.hotplug b/package/network/config/firewall/files/reflection.hotplug new file mode 100644 index 0000000..129a922 --- /dev/null +++ b/package/network/config/firewall/files/reflection.hotplug @@ -0,0 +1,169 @@ +#!/bin/sh + +. /lib/functions.sh +. /lib/functions/network.sh + +if [ "$ACTION" = "remove" ]; then + + delete_rules_by_comment() { + local table="$1" + local chain="$2" + local comment="$3" + + iptables -t "$table" --line-numbers -nL "$chain" 2>/dev/null | \ + sed -e ' + 1d; + 1! { + \#^[0-9]\+ .* /\* '"$comment"' \*/.*$# { + s/ .*$//; + G; h; + } + }; + $!d; + ' | xargs -n1 iptables -t "$table" -D "$chain" 2>/dev/null + } + + delete_rules_by_comment nat nat_reflection_in "$INTERFACE" + delete_rules_by_comment nat nat_reflection_out "$INTERFACE" + delete_rules_by_comment filter nat_reflection_fwd "$INTERFACE" + +elif [ "$ACTION" = "add" ]; then + + prepare_chains() { + iptables -t nat -N nat_reflection_in 2>/dev/null && { + iptables -t nat -A prerouting_rule -j nat_reflection_in + } + + iptables -t nat -N nat_reflection_out 2>/dev/null && { + iptables -t nat -A postrouting_rule -j nat_reflection_out + } + + iptables -t filter -N nat_reflection_fwd 2>/dev/null && { + iptables -t filter -A forwarding_rule -j nat_reflection_fwd + } + } + + find_networks() { + find_networks_cb() { + local cfg="$1" + local zone="$2" + local need_masq="${3:-0}" + + local name + config_get name "$cfg" name + + local masq + config_get_bool masq "$cfg" masq 0 + + [ "$name" = "$zone" ] && [ "$masq" -ge "$need_masq" ] && { + local network + config_get network "$cfg" network + + echo ${network:-$zone} + return 1 + } + } + + config_foreach find_networks_cb zone "$@" + } + + setup_fwd() { + local cfg="$1" + + local reflection + config_get_bool reflection "$cfg" reflection 1 + [ "$reflection" == 1 ] || return + + local src + config_get src "$cfg" src + [ "$src" == "$ZONE" ] || return + + local dest + config_get dest "$cfg" dest + [ "$dest" != "*" ] || return + + local target + config_get target "$cfg" target DNAT + [ "$target" = DNAT ] || return + + prepare_chains + + local net + for net in $(find_networks "$dest" 0); do + local intnet + network_get_subnet intnet "$net" || continue + + local proto + config_get proto "$cfg" proto + + local epmin epmax extport + config_get extport "$cfg" src_dport "1-65535" + [ -n "$extport" ] || return + + epmin="${extport%[-:]*}"; epmax="${extport#*[-:]}" + [ "${epmin#!}" != "$epmax" ] || epmax="" + + local ipmin ipmax intport + config_get intport "$cfg" dest_port "$extport" + + ipmin="${intport%[-:]*}"; ipmax="${intport#*[-:]}" + [ "${ipmin#!}" != "$ipmax" ] || ipmax="" + + local exthost + config_get exthost "$cfg" src_dip "$extip" + + local inthost + config_get inthost "$cfg" dest_ip + [ -n "$inthost" ] || return + + [ "$proto" = all ] && proto="tcp udp" + [ "$proto" = tcpudp ] && proto="tcp udp" + + [ "${inthost#!}" = "$inthost" ] || return 0 + [ "${exthost#!}" = "$exthost" ] || return 0 + + [ "${epmin#!}" != "$epmin" ] && \ + extport="! --dport ${epmin#!}${epmax:+:$epmax}" || \ + extport="--dport $epmin${epmax:+:$epmax}" + + [ "${ipmin#!}" != "$ipmin" ] && \ + intport="! --dport ${ipmin#!}${ipmax:+:$ipmax}" || \ + intport="--dport $ipmin${ipmax:+:$ipmax}" + + local p + for p in ${proto:-tcp udp}; do + case "$p" in + tcp|udp|6|17) + iptables -t nat -A nat_reflection_in \ + -s $intnet -d $exthost \ + -p $p $extport \ + -m comment --comment "$INTERFACE" \ + -j DNAT --to $inthost:${ipmin#!}${ipmax:+-$ipmax} + + iptables -t nat -A nat_reflection_out \ + -s $intnet -d $inthost \ + -p $p $intport \ + -m comment --comment "$INTERFACE" \ + -j SNAT --to-source ${intnet%%/*} + + iptables -t filter -A nat_reflection_fwd \ + -s $intnet -d $inthost \ + -p $p $intport \ + -m comment --comment "$INTERFACE" \ + -j ACCEPT + ;; + esac + done + done + } + + config_load firewall + + local is_masq_zone="$(find_networks "$ZONE" 1)" + [ -n "$is_masq_zone" ] || exit 0 + + local extip + network_get_ipaddr extip "$INTERFACE" || exit 0 + + config_foreach setup_fwd redirect +fi diff --git a/package/network/config/firewall3/.svn/entries b/package/network/config/firewall3/.svn/entries new file mode 100644 index 0000000..3f60200 --- /dev/null +++ b/package/network/config/firewall3/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/firewall3 +svn://svn.openwrt.org/openwrt + + + +2013-03-14T15:29:43.028686Z +36009 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +Makefile +file + + + + +2013-03-17T12:13:19.000000Z +d20f1407354143adf7bb3998da00ee47 +2013-03-14T15:29:43.028686Z +36009 +jow + + + + + + + + + + + + + + + + + + + + + +1520 + diff --git a/package/network/config/firewall3/.svn/text-base/Makefile.svn-base b/package/network/config/firewall3/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..6bd768c --- /dev/null +++ b/package/network/config/firewall3/.svn/text-base/Makefile.svn-base @@ -0,0 +1,54 @@ +# +# 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:=firewall3 +PKG_VERSION:=2013-03-14 +PKG_RELEASE:=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://nbd.name/firewall3.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=ab591095d650bc3e997bad12aa7662e49d5cd9d5 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org> + + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/firewall3 + SECTION:=net + CATEGORY:=Network + TITLE:=UCI C Firewall + DEPENDS:=+libubox +libubus +libuci +endef + +define Package/firewall3/description + This package provides a config-compatible C implementation of the UCI firewall. +endef + +define Package/firewall3/conffiles +/etc/config/firewall +/etc/firewall.user +endef + +define Package/firewall3/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 +endef + +$(eval $(call BuildPackage,firewall3)) diff --git a/package/network/config/firewall3/Makefile b/package/network/config/firewall3/Makefile new file mode 100644 index 0000000..6bd768c --- /dev/null +++ b/package/network/config/firewall3/Makefile @@ -0,0 +1,54 @@ +# +# 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:=firewall3 +PKG_VERSION:=2013-03-14 +PKG_RELEASE:=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://nbd.name/firewall3.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=ab591095d650bc3e997bad12aa7662e49d5cd9d5 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org> + + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/firewall3 + SECTION:=net + CATEGORY:=Network + TITLE:=UCI C Firewall + DEPENDS:=+libubox +libubus +libuci +endef + +define Package/firewall3/description + This package provides a config-compatible C implementation of the UCI firewall. +endef + +define Package/firewall3/conffiles +/etc/config/firewall +/etc/firewall.user +endef + +define Package/firewall3/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 +endef + +$(eval $(call BuildPackage,firewall3)) diff --git a/package/network/config/firewall3/files/.svn/entries b/package/network/config/firewall3/files/.svn/entries new file mode 100644 index 0000000..9baf8d9 --- /dev/null +++ b/package/network/config/firewall3/files/.svn/entries @@ -0,0 +1,164 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/firewall3/files +svn://svn.openwrt.org/openwrt + + + +2013-03-13T15:46:30.571192Z +35998 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +firewall.user +file + + + + +2013-03-17T12:13:19.000000Z +f482960e5c24821f077e601d9a7f3068 +2013-03-11T20:52:20.179524Z +35969 +jow + + + + + + + + + + + + + + + + + + + + + +352 + +firewall.hotplug +file + + + + +2013-03-17T12:13:19.000000Z +8d17f1b0dbce5fe0f59a693af482f2c5 +2013-03-13T15:46:30.571192Z +35998 +jow + + + + + + + + + + + + + + + + + + + + + +223 + +firewall.init +file + + + + +2013-03-17T12:13:19.000000Z +2c5f74740c6b69a390dfaf075f2e72a6 +2013-03-13T15:46:30.571192Z +35998 +jow +has-props + + + + + + + + + + + + + + + + + + + + +262 + +firewall.config +file + + + + +2013-03-17T12:13:19.000000Z +f952253dc6cb85d189857c3fead88362 +2013-03-05T13:45:09.488580Z +35889 +jow +has-props + + + + + + + + + + + + + + + + + + + + +4244 + diff --git a/package/network/config/firewall3/files/.svn/prop-base/firewall.config.svn-base b/package/network/config/firewall3/files/.svn/prop-base/firewall.config.svn-base new file mode 100644 index 0000000..3160658 --- /dev/null +++ b/package/network/config/firewall3/files/.svn/prop-base/firewall.config.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:mergeinfo +V 0 + +END diff --git a/package/network/config/firewall3/files/.svn/prop-base/firewall.init.svn-base b/package/network/config/firewall3/files/.svn/prop-base/firewall.init.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/firewall3/files/.svn/prop-base/firewall.init.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/firewall3/files/.svn/text-base/firewall.config.svn-base b/package/network/config/firewall3/files/.svn/text-base/firewall.config.svn-base new file mode 100644 index 0000000..6acfe1e --- /dev/null +++ b/package/network/config/firewall3/files/.svn/text-base/firewall.config.svn-base @@ -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 + option network 'lan' + option input ACCEPT + option output ACCEPT + option forward REJECT + +config zone + option name wan + option network 'wan' + 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 + +# 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 fe80::/10 + option src_port 547 + option dest_ip fe80::/10 + option dest_port 546 + 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 + +# Block ULA-traffic from leaking out +config rule + option name Enforce-ULA-Border-Src + option src * + option dest wan + option proto all + option src_ip fc00::/7 + option family ipv6 + option target REJECT + +config rule + option name Enforce-ULA-Border-Dest + option src * + option dest wan + option proto all + option dest_ip fc00::/7 + option family ipv6 + option target REJECT + +# 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 + +# allow IPsec/ESP and ISAKMP passthrough +#config rule +# option src wan +# option dest lan +# option protocol esp +# option target ACCEPT + +#config rule +# option src wan +# option dest lan +# option src_port 500 +# option dest_port 500 +# option proto udp +# option target ACCEPT + +### 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 diff --git a/package/network/config/firewall3/files/.svn/text-base/firewall.hotplug.svn-base b/package/network/config/firewall3/files/.svn/text-base/firewall.hotplug.svn-base new file mode 100644 index 0000000..34f3afe --- /dev/null +++ b/package/network/config/firewall3/files/.svn/text-base/firewall.hotplug.svn-base @@ -0,0 +1,10 @@ +#!/bin/sh + +[ "$ACTION" = ifup ] || exit 0 + +/etc/init.d/firewall enabled || exit 0 + +fw3 -q network "$INTERFACE" >/dev/null || exit 0 + +logger -t firewall "Reloading firewall due to ifup of $INTERFACE ($DEVICE)" +fw3 -q reload diff --git a/package/network/config/firewall3/files/.svn/text-base/firewall.init.svn-base b/package/network/config/firewall3/files/.svn/text-base/firewall.init.svn-base new file mode 100644 index 0000000..64e3a8c --- /dev/null +++ b/package/network/config/firewall3/files/.svn/text-base/firewall.init.svn-base @@ -0,0 +1,25 @@ +#!/bin/sh /etc/rc.common + +START=19 + +boot() { + # Be silent on boot, firewall might be started by hotplug already, + # so don't complain in syslog. + fw3 -q start +} + +start() { + fw3 start +} + +stop() { + fw3 flush +} + +restart() { + fw3 restart +} + +reload() { + fw3 reload +} diff --git a/package/network/config/firewall3/files/.svn/text-base/firewall.user.svn-base b/package/network/config/firewall3/files/.svn/text-base/firewall.user.svn-base new file mode 100644 index 0000000..6f79906 --- /dev/null +++ b/package/network/config/firewall3/files/.svn/text-base/firewall.user.svn-base @@ -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. diff --git a/package/network/config/firewall3/files/firewall.config b/package/network/config/firewall3/files/firewall.config new file mode 100644 index 0000000..6acfe1e --- /dev/null +++ b/package/network/config/firewall3/files/firewall.config @@ -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 + option network 'lan' + option input ACCEPT + option output ACCEPT + option forward REJECT + +config zone + option name wan + option network 'wan' + 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 + +# 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 fe80::/10 + option src_port 547 + option dest_ip fe80::/10 + option dest_port 546 + 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 + +# Block ULA-traffic from leaking out +config rule + option name Enforce-ULA-Border-Src + option src * + option dest wan + option proto all + option src_ip fc00::/7 + option family ipv6 + option target REJECT + +config rule + option name Enforce-ULA-Border-Dest + option src * + option dest wan + option proto all + option dest_ip fc00::/7 + option family ipv6 + option target REJECT + +# 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 + +# allow IPsec/ESP and ISAKMP passthrough +#config rule +# option src wan +# option dest lan +# option protocol esp +# option target ACCEPT + +#config rule +# option src wan +# option dest lan +# option src_port 500 +# option dest_port 500 +# option proto udp +# option target ACCEPT + +### 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 diff --git a/package/network/config/firewall3/files/firewall.hotplug b/package/network/config/firewall3/files/firewall.hotplug new file mode 100644 index 0000000..34f3afe --- /dev/null +++ b/package/network/config/firewall3/files/firewall.hotplug @@ -0,0 +1,10 @@ +#!/bin/sh + +[ "$ACTION" = ifup ] || exit 0 + +/etc/init.d/firewall enabled || exit 0 + +fw3 -q network "$INTERFACE" >/dev/null || exit 0 + +logger -t firewall "Reloading firewall due to ifup of $INTERFACE ($DEVICE)" +fw3 -q reload diff --git a/package/network/config/firewall3/files/firewall.init b/package/network/config/firewall3/files/firewall.init new file mode 100755 index 0000000..64e3a8c --- /dev/null +++ b/package/network/config/firewall3/files/firewall.init @@ -0,0 +1,25 @@ +#!/bin/sh /etc/rc.common + +START=19 + +boot() { + # Be silent on boot, firewall might be started by hotplug already, + # so don't complain in syslog. + fw3 -q start +} + +start() { + fw3 start +} + +stop() { + fw3 flush +} + +restart() { + fw3 restart +} + +reload() { + fw3 reload +} diff --git a/package/network/config/firewall3/files/firewall.user b/package/network/config/firewall3/files/firewall.user new file mode 100644 index 0000000..6f79906 --- /dev/null +++ b/package/network/config/firewall3/files/firewall.user @@ -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. diff --git a/package/network/config/ltq-dsl-app/.svn/entries b/package/network/config/ltq-dsl-app/.svn/entries new file mode 100644 index 0000000..54817f2 --- /dev/null +++ b/package/network/config/ltq-dsl-app/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/ltq-dsl-app +svn://svn.openwrt.org/openwrt + + + +2012-12-15T02:00:39.596852Z +34694 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +patches +dir + diff --git a/package/network/config/ltq-dsl-app/patches/.svn/entries b/package/network/config/ltq-dsl-app/patches/.svn/entries new file mode 100644 index 0000000..0809305 --- /dev/null +++ b/package/network/config/ltq-dsl-app/patches/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/ltq-dsl-app/patches +svn://svn.openwrt.org/openwrt + + + +2012-12-03T12:46:57.108169Z +34468 +mirko + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +010-eglibc_compile_fix.patch +file + + + + +2013-03-17T12:13:19.000000Z +a5157ed81f90d27e4225ef82914554ae +2012-12-03T12:46:57.108169Z +34468 +mirko + + + + + + + + + + + + + + + + + + + + + +647 + diff --git a/package/network/config/ltq-dsl-app/patches/.svn/text-base/010-eglibc_compile_fix.patch.svn-base b/package/network/config/ltq-dsl-app/patches/.svn/text-base/010-eglibc_compile_fix.patch.svn-base new file mode 100644 index 0000000..268f868 --- /dev/null +++ b/package/network/config/ltq-dsl-app/patches/.svn/text-base/010-eglibc_compile_fix.patch.svn-base @@ -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> diff --git a/package/network/config/ltq-dsl-app/patches/010-eglibc_compile_fix.patch b/package/network/config/ltq-dsl-app/patches/010-eglibc_compile_fix.patch new file mode 100644 index 0000000..268f868 --- /dev/null +++ b/package/network/config/ltq-dsl-app/patches/010-eglibc_compile_fix.patch @@ -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> diff --git a/package/network/config/netifd/.svn/entries b/package/network/config/netifd/.svn/entries new file mode 100644 index 0000000..4ebc152 --- /dev/null +++ b/package/network/config/netifd/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd +svn://svn.openwrt.org/openwrt + + + +2013-02-22T08:56:29.298787Z +35743 +cyrus + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:19.000000Z +e416eb8345976b288affaabbe8ad909e +2013-02-22T08:56:29.298787Z +35743 +cyrus + + + + + + + + + + + + + + + + + + + + + +1139 + diff --git a/package/network/config/netifd/.svn/text-base/Makefile.svn-base b/package/network/config/netifd/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..ad27e2c --- /dev/null +++ b/package/network/config/netifd/.svn/text-base/Makefile.svn-base @@ -0,0 +1,46 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=netifd +PKG_VERSION:=2013-02-19 +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://nbd.name/luci2/netifd.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=486aa750a164d41905beb61afec89268e3eb7f48 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org> +# PKG_MIRROR_MD5SUM:= +# CMAKE_INSTALL:=1 + +PKG_LICENSE:=GPLv2 +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 + 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)/dummy/netifd-proto.sh $(1)/lib/netifd/ +endef + +$(eval $(call BuildPackage,netifd)) diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile new file mode 100644 index 0000000..ad27e2c --- /dev/null +++ b/package/network/config/netifd/Makefile @@ -0,0 +1,46 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=netifd +PKG_VERSION:=2013-02-19 +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://nbd.name/luci2/netifd.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=486aa750a164d41905beb61afec89268e3eb7f48 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org> +# PKG_MIRROR_MD5SUM:= +# CMAKE_INSTALL:=1 + +PKG_LICENSE:=GPLv2 +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 + 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)/dummy/netifd-proto.sh $(1)/lib/netifd/ +endef + +$(eval $(call BuildPackage,netifd)) diff --git a/package/network/config/netifd/files/.svn/entries b/package/network/config/netifd/files/.svn/entries new file mode 100644 index 0000000..1e86684 --- /dev/null +++ b/package/network/config/netifd/files/.svn/entries @@ -0,0 +1,40 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files +svn://svn.openwrt.org/openwrt + + + +2013-01-29T14:40:04.101944Z +35383 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +lib +dir + +usr +dir + +etc +dir + +sbin +dir + diff --git a/package/network/config/netifd/files/etc/.svn/entries b/package/network/config/netifd/files/etc/.svn/entries new file mode 100644 index 0000000..8be2c35 --- /dev/null +++ b/package/network/config/netifd/files/etc/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/etc +svn://svn.openwrt.org/openwrt + + + +2013-01-29T10:13:39.572932Z +35369 +cyrus + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +hotplug.d +dir + +init.d +dir + diff --git a/package/network/config/netifd/files/etc/hotplug.d/.svn/entries b/package/network/config/netifd/files/etc/hotplug.d/.svn/entries new file mode 100644 index 0000000..22338da --- /dev/null +++ b/package/network/config/netifd/files/etc/hotplug.d/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/etc/hotplug.d +svn://svn.openwrt.org/openwrt + + + +2013-01-29T10:13:39.572932Z +35369 +cyrus + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +iface +dir + diff --git a/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/entries b/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/entries new file mode 100644 index 0000000..5810f6a --- /dev/null +++ b/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/etc/hotplug.d/iface +svn://svn.openwrt.org/openwrt + + + +2013-01-29T10:13:39.572932Z +35369 +cyrus + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +00-netstate +file + + + + +2013-03-17T12:13:19.000000Z +07e4cbee0469ae27ace1efa977b04eae +2012-02-03T10:17:30.884717Z +30008 +nbd + + + + + + + + + + + + + + + + + + + + + +337 + +10-ipv6-static +file + + + + +2013-03-17T12:13:19.000000Z +97591c010e5989d4f29cb5bc616f9e73 +2013-01-29T10:13:39.572932Z +35369 +cyrus + + + + + + + + + + + + + + + + + + + + + +487 + diff --git a/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/text-base/00-netstate.svn-base b/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/text-base/00-netstate.svn-base new file mode 100644 index 0000000..c50cda6 --- /dev/null +++ b/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/text-base/00-netstate.svn-base @@ -0,0 +1,8 @@ +[ ifup = "$ACTION" ] && { + uci_toggle_state network "$INTERFACE" up 1 + uci_toggle_state network "$INTERFACE" connect_time $(sed -ne 's![^0-9].*$!!p' /proc/uptime) + [ -n "$DEVICE" ] && { + uci_toggle_state network "$INTERFACE" device "$(uci -q get network.$INTERFACE.ifname)" + uci_toggle_state network "$INTERFACE" ifname "$DEVICE" + } +} diff --git a/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/text-base/10-ipv6-static.svn-base b/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/text-base/10-ipv6-static.svn-base new file mode 100644 index 0000000..d724894 --- /dev/null +++ b/package/network/config/netifd/files/etc/hotplug.d/iface/.svn/text-base/10-ipv6-static.svn-base @@ -0,0 +1,19 @@ +case "$ACTION" in + ifup) + . /lib/functions.sh + + local proto ip6slaac + config_load network + config_get proto "$INTERFACE" proto + config_get_bool ip6slaac "$INTERFACE" ip6slaac + + if [ "$proto" = "static" -a "$ip6slaac" = "1" ]; then + echo 2 > "/proc/sys/net/ipv6/conf/$DEVICE/accept_ra" + + # Though this should be save here, it is not recommended + echo 1 > "/proc/sys/net/ipv6/conf/$DEVICE/disable_ipv6" + echo 0 > "/proc/sys/net/ipv6/conf/$DEVICE/disable_ipv6" + fi + ;; +esac + diff --git a/package/network/config/netifd/files/etc/hotplug.d/iface/00-netstate b/package/network/config/netifd/files/etc/hotplug.d/iface/00-netstate new file mode 100644 index 0000000..c50cda6 --- /dev/null +++ b/package/network/config/netifd/files/etc/hotplug.d/iface/00-netstate @@ -0,0 +1,8 @@ +[ ifup = "$ACTION" ] && { + uci_toggle_state network "$INTERFACE" up 1 + uci_toggle_state network "$INTERFACE" connect_time $(sed -ne 's![^0-9].*$!!p' /proc/uptime) + [ -n "$DEVICE" ] && { + uci_toggle_state network "$INTERFACE" device "$(uci -q get network.$INTERFACE.ifname)" + uci_toggle_state network "$INTERFACE" ifname "$DEVICE" + } +} diff --git a/package/network/config/netifd/files/etc/hotplug.d/iface/10-ipv6-static b/package/network/config/netifd/files/etc/hotplug.d/iface/10-ipv6-static new file mode 100644 index 0000000..d724894 --- /dev/null +++ b/package/network/config/netifd/files/etc/hotplug.d/iface/10-ipv6-static @@ -0,0 +1,19 @@ +case "$ACTION" in + ifup) + . /lib/functions.sh + + local proto ip6slaac + config_load network + config_get proto "$INTERFACE" proto + config_get_bool ip6slaac "$INTERFACE" ip6slaac + + if [ "$proto" = "static" -a "$ip6slaac" = "1" ]; then + echo 2 > "/proc/sys/net/ipv6/conf/$DEVICE/accept_ra" + + # Though this should be save here, it is not recommended + echo 1 > "/proc/sys/net/ipv6/conf/$DEVICE/disable_ipv6" + echo 0 > "/proc/sys/net/ipv6/conf/$DEVICE/disable_ipv6" + fi + ;; +esac + diff --git a/package/network/config/netifd/files/etc/init.d/.svn/entries b/package/network/config/netifd/files/etc/init.d/.svn/entries new file mode 100644 index 0000000..2520cee --- /dev/null +++ b/package/network/config/netifd/files/etc/init.d/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/etc/init.d +svn://svn.openwrt.org/openwrt + + + +2013-01-19T10:13:14.536731Z +35240 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +network +file + + + + +2013-03-17T12:13:19.000000Z +f013880fead70c81159a0bc5c2096c31 +2013-01-19T10:13:14.536731Z +35240 +jow +has-props + + + + + + + + + + + + + + + + + + + + +559 + diff --git a/package/network/config/netifd/files/etc/init.d/.svn/prop-base/network.svn-base b/package/network/config/netifd/files/etc/init.d/.svn/prop-base/network.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/etc/init.d/.svn/prop-base/network.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/etc/init.d/.svn/text-base/network.svn-base b/package/network/config/netifd/files/etc/init.d/.svn/text-base/network.svn-base new file mode 100644 index 0000000..429f33d --- /dev/null +++ b/package/network/config/netifd/files/etc/init.d/.svn/text-base/network.svn-base @@ -0,0 +1,47 @@ +#!/bin/sh /etc/rc.common + +START=20 +STOP=90 + +SERVICE_DAEMONIZE=1 +SERVICE_WRITE_PID=1 + +start() { + stop + [ -e /proc/sys/kernel/core_pattern ] && { + ulimit -c unlimited + echo '/tmp/%e.%p.%s.%t.core' > /proc/sys/kernel/core_pattern + } + service_start /sbin/netifd + + setup_switch() { return 0; } + + include /lib/network + setup_switch + + sleep 5 + + /sbin/wifi down + /sbin/wifi up +} + +restart() { + ifdown -a + sleep 1 + start +} + +shutdown() { + ifdown -a + stop +} + +stop() { + service_stop /sbin/netifd +} + +reload() { + ubus call network reload + /sbin/wifi down + /sbin/wifi up +} diff --git a/package/network/config/netifd/files/etc/init.d/network b/package/network/config/netifd/files/etc/init.d/network new file mode 100755 index 0000000..429f33d --- /dev/null +++ b/package/network/config/netifd/files/etc/init.d/network @@ -0,0 +1,47 @@ +#!/bin/sh /etc/rc.common + +START=20 +STOP=90 + +SERVICE_DAEMONIZE=1 +SERVICE_WRITE_PID=1 + +start() { + stop + [ -e /proc/sys/kernel/core_pattern ] && { + ulimit -c unlimited + echo '/tmp/%e.%p.%s.%t.core' > /proc/sys/kernel/core_pattern + } + service_start /sbin/netifd + + setup_switch() { return 0; } + + include /lib/network + setup_switch + + sleep 5 + + /sbin/wifi down + /sbin/wifi up +} + +restart() { + ifdown -a + sleep 1 + start +} + +shutdown() { + ifdown -a + stop +} + +stop() { + service_stop /sbin/netifd +} + +reload() { + ubus call network reload + /sbin/wifi down + /sbin/wifi up +} diff --git a/package/network/config/netifd/files/lib/.svn/entries b/package/network/config/netifd/files/lib/.svn/entries new file mode 100644 index 0000000..72f9274 --- /dev/null +++ b/package/network/config/netifd/files/lib/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/lib +svn://svn.openwrt.org/openwrt + + + +2012-12-15T17:19:24.809183Z +34704 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +netifd +dir + +network +dir + diff --git a/package/network/config/netifd/files/lib/netifd/.svn/entries b/package/network/config/netifd/files/lib/netifd/.svn/entries new file mode 100644 index 0000000..96910c4 --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/lib/netifd +svn://svn.openwrt.org/openwrt + + + +2012-12-15T17:19:24.809183Z +34704 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +dhcp.script +file + + + + +2013-03-17T12:13:19.000000Z +1693935249ca21d6ee4b449e363eab81 +2012-12-15T17:19:24.809183Z +34704 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +1392 + +proto +dir + diff --git a/package/network/config/netifd/files/lib/netifd/.svn/prop-base/dhcp.script.svn-base b/package/network/config/netifd/files/lib/netifd/.svn/prop-base/dhcp.script.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/.svn/prop-base/dhcp.script.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/lib/netifd/.svn/text-base/dhcp.script.svn-base b/package/network/config/netifd/files/lib/netifd/.svn/text-base/dhcp.script.svn-base new file mode 100644 index 0000000..d26db0f --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/.svn/text-base/dhcp.script.svn-base @@ -0,0 +1,62 @@ +#!/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 + local type + while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do + proto_add_ipv4_route "${1%%/*}" "${1##*/}" "$2" + 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 + + for i in $router; do + proto_add_ipv4_route 0.0.0.0 0 "$i" + done + + # CIDR STATIC ROUTES (rfc3442) + [ -n "$staticroutes" ] && set_classless_routes $staticroutes + [ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes + + for dns in $dns; do + proto_add_dns_server "$dns" + done + for domain in $domain; do + proto_add_dns_search "$domain" + done + proto_send_update "$INTERFACE" + + # TODO + # [ -n "$ntpsrv" ] && change_state network "$ifc" lease_ntpsrv "$ntpsrv" + # [ -n "$timesvr" ] && change_state network "$ifc" lease_timesrv "$timesvr" + # [ -n "$hostname" ] && change_state network "$ifc" lease_hostname "$hostname" + # [ -n "$timezone" ] && change_state network "$ifc" lease_timezone "$timezone" +} + +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 diff --git a/package/network/config/netifd/files/lib/netifd/dhcp.script b/package/network/config/netifd/files/lib/netifd/dhcp.script new file mode 100755 index 0000000..d26db0f --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/dhcp.script @@ -0,0 +1,62 @@ +#!/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 + local type + while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do + proto_add_ipv4_route "${1%%/*}" "${1##*/}" "$2" + 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 + + for i in $router; do + proto_add_ipv4_route 0.0.0.0 0 "$i" + done + + # CIDR STATIC ROUTES (rfc3442) + [ -n "$staticroutes" ] && set_classless_routes $staticroutes + [ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes + + for dns in $dns; do + proto_add_dns_server "$dns" + done + for domain in $domain; do + proto_add_dns_search "$domain" + done + proto_send_update "$INTERFACE" + + # TODO + # [ -n "$ntpsrv" ] && change_state network "$ifc" lease_ntpsrv "$ntpsrv" + # [ -n "$timesvr" ] && change_state network "$ifc" lease_timesrv "$timesvr" + # [ -n "$hostname" ] && change_state network "$ifc" lease_hostname "$hostname" + # [ -n "$timezone" ] && change_state network "$ifc" lease_timezone "$timezone" +} + +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 diff --git a/package/network/config/netifd/files/lib/netifd/proto/.svn/entries b/package/network/config/netifd/files/lib/netifd/proto/.svn/entries new file mode 100644 index 0000000..627c4de --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/proto/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/lib/netifd/proto +svn://svn.openwrt.org/openwrt + + + +2012-11-05T19:28:24.248597Z +34089 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +dhcp.sh +file + + + + +2013-03-17T12:13:19.000000Z +53542ed23c9805277cc02e3d7dc0a307 +2012-11-05T19:28:24.248597Z +34089 +jow +has-props + + + + + + + + + + + + + + + + + + + + +1129 + diff --git a/package/network/config/netifd/files/lib/netifd/proto/.svn/prop-base/dhcp.sh.svn-base b/package/network/config/netifd/files/lib/netifd/proto/.svn/prop-base/dhcp.sh.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/proto/.svn/prop-base/dhcp.sh.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/lib/netifd/proto/.svn/text-base/dhcp.sh.svn-base b/package/network/config/netifd/files/lib/netifd/proto/.svn/text-base/dhcp.sh.svn-base new file mode 100644 index 0000000..3830878 --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/proto/.svn/text-base/dhcp.sh.svn-base @@ -0,0 +1,49 @@ +#!/bin/sh + +. /lib/functions.sh +. ../netifd-proto.sh +init_proto "$@" + +proto_dhcp_init_config() { + proto_config_add_string "ipaddr" + proto_config_add_string "netmask" + proto_config_add_string "hostname" + proto_config_add_string "clientid" + proto_config_add_string "vendorid" + proto_config_add_boolean "broadcast" + proto_config_add_string "reqopts" +} + +proto_dhcp_setup() { + local config="$1" + local iface="$2" + + local ipaddr hostname clientid vendorid broadcast reqopts + json_get_vars ipaddr hostname clientid vendorid broadcast reqopts + + local opt dhcpopts + for opt in $reqopts; do + append dhcpopts "-O $opt" + done + + [ "$broadcast" = 1 ] && broadcast="-B" || broadcast= + [ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" || clientid="-C" + + 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:+-H $hostname} \ + ${vendorid:+-V $vendorid} \ + $clientid $broadcast $dhcpopts +} + +proto_dhcp_teardown() { + local interface="$1" + proto_kill_command "$interface" +} + +add_protocol dhcp + diff --git a/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh new file mode 100755 index 0000000..3830878 --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/proto/dhcp.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +. /lib/functions.sh +. ../netifd-proto.sh +init_proto "$@" + +proto_dhcp_init_config() { + proto_config_add_string "ipaddr" + proto_config_add_string "netmask" + proto_config_add_string "hostname" + proto_config_add_string "clientid" + proto_config_add_string "vendorid" + proto_config_add_boolean "broadcast" + proto_config_add_string "reqopts" +} + +proto_dhcp_setup() { + local config="$1" + local iface="$2" + + local ipaddr hostname clientid vendorid broadcast reqopts + json_get_vars ipaddr hostname clientid vendorid broadcast reqopts + + local opt dhcpopts + for opt in $reqopts; do + append dhcpopts "-O $opt" + done + + [ "$broadcast" = 1 ] && broadcast="-B" || broadcast= + [ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" || clientid="-C" + + 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:+-H $hostname} \ + ${vendorid:+-V $vendorid} \ + $clientid $broadcast $dhcpopts +} + +proto_dhcp_teardown() { + local interface="$1" + proto_kill_command "$interface" +} + +add_protocol dhcp + diff --git a/package/network/config/netifd/files/lib/network/.svn/entries b/package/network/config/netifd/files/lib/network/.svn/entries new file mode 100644 index 0000000..249cb3c --- /dev/null +++ b/package/network/config/netifd/files/lib/network/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/lib/network +svn://svn.openwrt.org/openwrt + + + +2012-06-11T13:25:58.910765Z +32192 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +config.sh +file + + + + +2013-03-17T12:13:19.000000Z +12ee7e8a4599ad1948c9bf50e5bb0532 +2012-06-11T13:25:58.910765Z +32192 +jow +has-props + + + + + + + + + + + + + + + + + + + + +1607 + diff --git a/package/network/config/netifd/files/lib/network/.svn/prop-base/config.sh.svn-base b/package/network/config/netifd/files/lib/network/.svn/prop-base/config.sh.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/lib/network/.svn/prop-base/config.sh.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/lib/network/.svn/text-base/config.sh.svn-base b/package/network/config/netifd/files/lib/network/.svn/text-base/config.sh.svn-base new file mode 100644 index 0000000..9128971 --- /dev/null +++ b/package/network/config/netifd/files/lib/network/.svn/text-base/config.sh.svn-base @@ -0,0 +1,79 @@ +#!/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 + config_get device "$config" device "$ifname" + [ "bridge" = "$type" ] && ifname="br-$config" + config_set "$config" device "$ifname" + 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" + config_set "$config" device "$device" +} + +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" +} diff --git a/package/network/config/netifd/files/lib/network/config.sh b/package/network/config/netifd/files/lib/network/config.sh new file mode 100755 index 0000000..9128971 --- /dev/null +++ b/package/network/config/netifd/files/lib/network/config.sh @@ -0,0 +1,79 @@ +#!/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 + config_get device "$config" device "$ifname" + [ "bridge" = "$type" ] && ifname="br-$config" + config_set "$config" device "$ifname" + 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" + config_set "$config" device "$device" +} + +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" +} diff --git a/package/network/config/netifd/files/sbin/.svn/entries b/package/network/config/netifd/files/sbin/.svn/entries new file mode 100644 index 0000000..b8927cc --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/entries @@ -0,0 +1,164 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/sbin +svn://svn.openwrt.org/openwrt + + + +2013-01-29T14:40:04.101944Z +35383 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +devstatus +file + + + + +2013-03-17T12:13:19.000000Z +97e78aed908f5b22479f2482492aee86 +2011-10-23T17:22:14.121936Z +28545 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +200 + +ifstatus +file + + + + +2013-03-17T12:13:19.000000Z +31a12bb1ab197fdc24f7d4a0288ab681 +2013-01-29T14:40:04.101944Z +35383 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +273 + +ifup +file + + + + +2013-03-17T12:13:19.000000Z +1d80dbe8b2dd7b5fb6b8de73a2881e85 +2013-01-29T14:40:04.101944Z +35383 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +1320 + +ifdown +file + + + + +2013-03-17T12:13:19.000000Z +7da3b21f78698f9c8d1fd0ed92022a46 +2011-10-21T01:47:49.907205Z +28499 +nbd +has-props + + +svn:special + + + + + + + + + + + + + + + + + +4 + diff --git a/package/network/config/netifd/files/sbin/.svn/prop-base/devstatus.svn-base b/package/network/config/netifd/files/sbin/.svn/prop-base/devstatus.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/prop-base/devstatus.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/sbin/.svn/prop-base/ifdown.svn-base b/package/network/config/netifd/files/sbin/.svn/prop-base/ifdown.svn-base new file mode 100644 index 0000000..d222469 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/prop-base/ifdown.svn-base @@ -0,0 +1,5 @@ +K 11 +svn:special +V 1 +* +END diff --git a/package/network/config/netifd/files/sbin/.svn/prop-base/ifstatus.svn-base b/package/network/config/netifd/files/sbin/.svn/prop-base/ifstatus.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/prop-base/ifstatus.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/sbin/.svn/prop-base/ifup.svn-base b/package/network/config/netifd/files/sbin/.svn/prop-base/ifup.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/prop-base/ifup.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/sbin/.svn/text-base/devstatus.svn-base b/package/network/config/netifd/files/sbin/.svn/text-base/devstatus.svn-base new file mode 100644 index 0000000..3c35b26 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/text-base/devstatus.svn-base @@ -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)" diff --git a/package/network/config/netifd/files/sbin/.svn/text-base/ifdown.svn-base b/package/network/config/netifd/files/sbin/.svn/text-base/ifdown.svn-base new file mode 100644 index 0000000..a687b74 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/text-base/ifdown.svn-base @@ -0,0 +1 @@ +link ifup
\ No newline at end of file diff --git a/package/network/config/netifd/files/sbin/.svn/text-base/ifstatus.svn-base b/package/network/config/netifd/files/sbin/.svn/text-base/ifstatus.svn-base new file mode 100644 index 0000000..8a951e6 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/text-base/ifstatus.svn-base @@ -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\" }" diff --git a/package/network/config/netifd/files/sbin/.svn/text-base/ifup.svn-base b/package/network/config/netifd/files/sbin/.svn/text-base/ifup.svn-base new file mode 100644 index 0000000..af3aaa8 --- /dev/null +++ b/package/network/config/netifd/files/sbin/.svn/text-base/ifup.svn-base @@ -0,0 +1,79 @@ +#!/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 + } + + local radio_devs + local network="$1" + config_load wireless + config_foreach find_related_radios wifi-iface + + local dev + for dev in $(echo "$radio_devs" | sort -u); do + /sbin/wifi up "$dev" + done +fi diff --git a/package/network/config/netifd/files/sbin/devstatus b/package/network/config/netifd/files/sbin/devstatus new file mode 100755 index 0000000..3c35b26 --- /dev/null +++ b/package/network/config/netifd/files/sbin/devstatus @@ -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)" diff --git a/package/network/config/netifd/files/sbin/ifdown b/package/network/config/netifd/files/sbin/ifdown new file mode 120000 index 0000000..a0e5c17 --- /dev/null +++ b/package/network/config/netifd/files/sbin/ifdown @@ -0,0 +1 @@ +ifup
\ No newline at end of file diff --git a/package/network/config/netifd/files/sbin/ifstatus b/package/network/config/netifd/files/sbin/ifstatus new file mode 100755 index 0000000..8a951e6 --- /dev/null +++ b/package/network/config/netifd/files/sbin/ifstatus @@ -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\" }" diff --git a/package/network/config/netifd/files/sbin/ifup b/package/network/config/netifd/files/sbin/ifup new file mode 100755 index 0000000..af3aaa8 --- /dev/null +++ b/package/network/config/netifd/files/sbin/ifup @@ -0,0 +1,79 @@ +#!/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 + } + + local radio_devs + local network="$1" + config_load wireless + config_foreach find_related_radios wifi-iface + + local dev + for dev in $(echo "$radio_devs" | sort -u); do + /sbin/wifi up "$dev" + done +fi diff --git a/package/network/config/netifd/files/usr/.svn/entries b/package/network/config/netifd/files/usr/.svn/entries new file mode 100644 index 0000000..1f099cf --- /dev/null +++ b/package/network/config/netifd/files/usr/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/usr +svn://svn.openwrt.org/openwrt + + + +2012-02-27T16:23:39.874148Z +30741 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +share +dir + diff --git a/package/network/config/netifd/files/usr/share/.svn/entries b/package/network/config/netifd/files/usr/share/.svn/entries new file mode 100644 index 0000000..b436dab --- /dev/null +++ b/package/network/config/netifd/files/usr/share/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/usr/share +svn://svn.openwrt.org/openwrt + + + +2012-02-27T16:23:39.874148Z +30741 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +udhcpc +dir + diff --git a/package/network/config/netifd/files/usr/share/udhcpc/.svn/entries b/package/network/config/netifd/files/usr/share/udhcpc/.svn/entries new file mode 100644 index 0000000..602e48d --- /dev/null +++ b/package/network/config/netifd/files/usr/share/udhcpc/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/files/usr/share/udhcpc +svn://svn.openwrt.org/openwrt + + + +2012-02-27T16:23:39.874148Z +30741 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +default.script +file + + + + +2013-03-17T12:13:19.000000Z +021bccd0bcd3a0f5f6166fccc54ef30d +2012-02-27T16:23:39.874148Z +30741 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +1346 + diff --git a/package/network/config/netifd/files/usr/share/udhcpc/.svn/prop-base/default.script.svn-base b/package/network/config/netifd/files/usr/share/udhcpc/.svn/prop-base/default.script.svn-base new file mode 100644 index 0000000..869ac71 --- /dev/null +++ b/package/network/config/netifd/files/usr/share/udhcpc/.svn/prop-base/default.script.svn-base @@ -0,0 +1,5 @@ +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/netifd/files/usr/share/udhcpc/.svn/text-base/default.script.svn-base b/package/network/config/netifd/files/usr/share/udhcpc/.svn/text-base/default.script.svn-base new file mode 100644 index 0000000..ac765a6 --- /dev/null +++ b/package/network/config/netifd/files/usr/share/udhcpc/.svn/text-base/default.script.svn-base @@ -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 diff --git a/package/network/config/netifd/files/usr/share/udhcpc/default.script b/package/network/config/netifd/files/usr/share/udhcpc/default.script new file mode 100755 index 0000000..ac765a6 --- /dev/null +++ b/package/network/config/netifd/files/usr/share/udhcpc/default.script @@ -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 diff --git a/package/network/config/netifd/patches/.svn/entries b/package/network/config/netifd/patches/.svn/entries new file mode 100644 index 0000000..bddbcdf --- /dev/null +++ b/package/network/config/netifd/patches/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/netifd/patches +svn://svn.openwrt.org/openwrt + + + +2012-11-23T20:02:10.520862Z +34310 +florian + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +001-musl_af_inet_include.patch +file + + + + +2013-03-17T12:13:19.000000Z +ef2db5f9cbc33fb642df085540830c2b +2012-11-23T20:02:10.520862Z +34310 +florian + + + + + + + + + + + + + + + + + + + + + +369 + diff --git a/package/network/config/netifd/patches/.svn/text-base/001-musl_af_inet_include.patch.svn-base b/package/network/config/netifd/patches/.svn/text-base/001-musl_af_inet_include.patch.svn-base new file mode 100644 index 0000000..510ee05 --- /dev/null +++ b/package/network/config/netifd/patches/.svn/text-base/001-musl_af_inet_include.patch.svn-base @@ -0,0 +1,11 @@ +diff -urN netifd-2012-10-29/utils.c netifd-2012-10-29.new/utils.c +--- netifd-2012-10-29/utils.c 2012-11-23 17:15:39.000000000 +0100 ++++ netifd-2012-10-29.new/utils.c 2012-11-23 17:16:53.409244361 +0100 +@@ -17,6 +17,7 @@ + + #include <arpa/inet.h> + #include <netinet/in.h> ++#include <sys/socket.h> + + void + __vlist_simple_init(struct vlist_simple_tree *tree, int offset) diff --git a/package/network/config/netifd/patches/001-musl_af_inet_include.patch b/package/network/config/netifd/patches/001-musl_af_inet_include.patch new file mode 100644 index 0000000..510ee05 --- /dev/null +++ b/package/network/config/netifd/patches/001-musl_af_inet_include.patch @@ -0,0 +1,11 @@ +diff -urN netifd-2012-10-29/utils.c netifd-2012-10-29.new/utils.c +--- netifd-2012-10-29/utils.c 2012-11-23 17:15:39.000000000 +0100 ++++ netifd-2012-10-29.new/utils.c 2012-11-23 17:16:53.409244361 +0100 +@@ -17,6 +17,7 @@ + + #include <arpa/inet.h> + #include <netinet/in.h> ++#include <sys/socket.h> + + void + __vlist_simple_init(struct vlist_simple_tree *tree, int offset) diff --git a/package/network/config/qos-scripts/.svn/entries b/package/network/config/qos-scripts/.svn/entries new file mode 100644 index 0000000..d29257b --- /dev/null +++ b/package/network/config/qos-scripts/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts +svn://svn.openwrt.org/openwrt + + + +2012-10-10T12:49:37.020840Z +33693 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +0a6610a4956deecf01760c0452296a6d +2012-10-10T12:49:37.020840Z +33693 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +1090 + diff --git a/package/network/config/qos-scripts/.svn/prop-base/Makefile.svn-base b/package/network/config/qos-scripts/.svn/prop-base/Makefile.svn-base new file mode 100644 index 0000000..8e522ae --- /dev/null +++ b/package/network/config/qos-scripts/.svn/prop-base/Makefile.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:copyright +V 30 +Copyright (C) 2006 OpenWrt.org +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/network/config/qos-scripts/.svn/text-base/Makefile.svn-base b/package/network/config/qos-scripts/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..a6690a1 --- /dev/null +++ b/package/network/config/qos-scripts/.svn/text-base/Makefile.svn-base @@ -0,0 +1,52 @@ +# +# Copyright (C) 2006-2011 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.2.1 +PKG_RELEASE:=6 + +PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org> + +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-filter +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)) diff --git a/package/network/config/qos-scripts/Makefile b/package/network/config/qos-scripts/Makefile new file mode 100644 index 0000000..a6690a1 --- /dev/null +++ b/package/network/config/qos-scripts/Makefile @@ -0,0 +1,52 @@ +# +# Copyright (C) 2006-2011 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.2.1 +PKG_RELEASE:=6 + +PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org> + +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-filter +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)) diff --git a/package/network/config/qos-scripts/files/.svn/entries b/package/network/config/qos-scripts/files/.svn/entries new file mode 100644 index 0000000..1ea9077 --- /dev/null +++ b/package/network/config/qos-scripts/files/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files +svn://svn.openwrt.org/openwrt + + + +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +usr +dir + +etc +dir + diff --git a/package/network/config/qos-scripts/files/etc/.svn/entries b/package/network/config/qos-scripts/files/etc/.svn/entries new file mode 100644 index 0000000..2a1a6ef --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/.svn/entries @@ -0,0 +1,37 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/etc +svn://svn.openwrt.org/openwrt + + + +2011-07-29T16:32:55.150774Z +27832 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +hotplug.d +dir + +config +dir + +init.d +dir + diff --git a/package/network/config/qos-scripts/files/etc/config/.svn/entries b/package/network/config/qos-scripts/files/etc/config/.svn/entries new file mode 100644 index 0000000..3d715dd --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/config/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/etc/config +svn://svn.openwrt.org/openwrt + + + +2011-07-29T16:32:55.150774Z +27832 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +qos +file + + + + +2013-03-17T12:13:20.000000Z +c67dad39ee194bbdb1a2b7952a436617 +2011-07-29T16:32:55.150774Z +27832 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +1773 + diff --git a/package/network/config/qos-scripts/files/etc/config/.svn/prop-base/qos.svn-base b/package/network/config/qos-scripts/files/etc/config/.svn/prop-base/qos.svn-base new file mode 100644 index 0000000..bdbd305 --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/config/.svn/prop-base/qos.svn-base @@ -0,0 +1,5 @@ +K 13 +svn:eol-style +V 6 +native +END diff --git a/package/network/config/qos-scripts/files/etc/config/.svn/text-base/qos.svn-base b/package/network/config/qos-scripts/files/etc/config/.svn/text-base/qos.svn-base new file mode 100644 index 0000000..8faff18 --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/config/.svn/text-base/qos.svn-base @@ -0,0 +1,79 @@ +# 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" +config classify + option target "Normal" + option proto "tcp" + option ports "20,21,25,80,110,443,993,995" +config classify + option target "Express" + option ports "5190" +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" +config reclassify + option target "Priority" + option proto "tcp" + option pktsize "-128" + option mark "!Bulk" + option tcpflags "SYN" +config reclassify + option target "Priority" + option proto "tcp" + option pktsize "-128" + option mark "!Bulk" + option tcpflags "ACK" + + +# 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 maxsize 400 + option avgrate 10 + option priority 20 +config class "Priority_down" + option packetsize 1000 + option avgrate 10 + + +config class "Express" + option packetsize 1000 + option maxsize 800 + 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 diff --git a/package/network/config/qos-scripts/files/etc/config/qos b/package/network/config/qos-scripts/files/etc/config/qos new file mode 100644 index 0000000..8faff18 --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/config/qos @@ -0,0 +1,79 @@ +# 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" +config classify + option target "Normal" + option proto "tcp" + option ports "20,21,25,80,110,443,993,995" +config classify + option target "Express" + option ports "5190" +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" +config reclassify + option target "Priority" + option proto "tcp" + option pktsize "-128" + option mark "!Bulk" + option tcpflags "SYN" +config reclassify + option target "Priority" + option proto "tcp" + option pktsize "-128" + option mark "!Bulk" + option tcpflags "ACK" + + +# 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 maxsize 400 + option avgrate 10 + option priority 20 +config class "Priority_down" + option packetsize 1000 + option avgrate 10 + + +config class "Express" + option packetsize 1000 + option maxsize 800 + 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 diff --git a/package/network/config/qos-scripts/files/etc/hotplug.d/.svn/entries b/package/network/config/qos-scripts/files/etc/hotplug.d/.svn/entries new file mode 100644 index 0000000..06c8595 --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/hotplug.d/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/etc/hotplug.d +svn://svn.openwrt.org/openwrt + + + +2007-09-27T14:06:07.234823Z +9046 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +iface +dir + diff --git a/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/entries b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/entries new file mode 100644 index 0000000..97d17a2 --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/etc/hotplug.d/iface +svn://svn.openwrt.org/openwrt + + + +2007-09-27T14:06:07.234823Z +9046 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +10-qos +file + + + + +2013-03-17T12:13:20.000000Z +19424796e16c97fce7a4dd2b01abf796 +2007-09-27T14:06:07.234823Z +9046 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +114 + diff --git a/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/prop-base/10-qos.svn-base b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/prop-base/10-qos.svn-base new file mode 100644 index 0000000..03b5bfa --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/prop-base/10-qos.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:eol-style +V 6 +native +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/text-base/10-qos.svn-base b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/text-base/10-qos.svn-base new file mode 100644 index 0000000..0ced29a --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/.svn/text-base/10-qos.svn-base @@ -0,0 +1,2 @@ +#!/bin/sh +[ "$ACTION" = ifup ] && /etc/init.d/qos enabled && /usr/lib/qos/generate.sh interface "$INTERFACE" | sh diff --git a/package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos new file mode 100755 index 0000000..0ced29a --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/hotplug.d/iface/10-qos @@ -0,0 +1,2 @@ +#!/bin/sh +[ "$ACTION" = ifup ] && /etc/init.d/qos enabled && /usr/lib/qos/generate.sh interface "$INTERFACE" | sh diff --git a/package/network/config/qos-scripts/files/etc/init.d/.svn/entries b/package/network/config/qos-scripts/files/etc/init.d/.svn/entries new file mode 100644 index 0000000..d7af9db --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/init.d/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/etc/init.d +svn://svn.openwrt.org/openwrt + + + +2007-04-06T16:59:56.568018Z +6875 +nbd + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +qos +file + + + + +2013-03-17T12:13:21.000000Z +da7c53be1fa334d195f786760d1dac3f +2007-04-06T16:59:56.568018Z +6875 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +166 + diff --git a/package/network/config/qos-scripts/files/etc/init.d/.svn/prop-base/qos.svn-base b/package/network/config/qos-scripts/files/etc/init.d/.svn/prop-base/qos.svn-base new file mode 100644 index 0000000..03b5bfa --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/init.d/.svn/prop-base/qos.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:eol-style +V 6 +native +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/qos-scripts/files/etc/init.d/.svn/text-base/qos.svn-base b/package/network/config/qos-scripts/files/etc/init.d/.svn/text-base/qos.svn-base new file mode 100644 index 0000000..3f71115 --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/init.d/.svn/text-base/qos.svn-base @@ -0,0 +1,16 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +START=50 + +boot() { + /usr/lib/qos/generate.sh firewall | sh +} + +start() { + qos-start +} + +stop() { + qos-stop +} diff --git a/package/network/config/qos-scripts/files/etc/init.d/qos b/package/network/config/qos-scripts/files/etc/init.d/qos new file mode 100755 index 0000000..3f71115 --- /dev/null +++ b/package/network/config/qos-scripts/files/etc/init.d/qos @@ -0,0 +1,16 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +START=50 + +boot() { + /usr/lib/qos/generate.sh firewall | sh +} + +start() { + qos-start +} + +stop() { + qos-stop +} diff --git a/package/network/config/qos-scripts/files/usr/.svn/entries b/package/network/config/qos-scripts/files/usr/.svn/entries new file mode 100644 index 0000000..c2f08c5 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/usr +svn://svn.openwrt.org/openwrt + + + +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +lib +dir + +bin +dir + diff --git a/package/network/config/qos-scripts/files/usr/bin/.svn/entries b/package/network/config/qos-scripts/files/usr/bin/.svn/entries new file mode 100644 index 0000000..fa60ae7 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/.svn/entries @@ -0,0 +1,130 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/usr/bin +svn://svn.openwrt.org/openwrt + + + +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +qos-stop +file + + + + +2013-03-17T12:13:19.000000Z +d0c4c982503c87ad4984bccf1f8396ec +2011-10-27T12:39:19.714355Z +28623 +jow +has-props + + + + + + + + + + + + + + + + + + + + +224 + +qos-stat +file + + + + +2013-03-17T12:13:19.000000Z +8698b43c858ec4bc03de0270308c4c79 +2012-06-05T16:04:23.055438Z +32062 +jow +has-props + + + + + + + + + + + + + + + + + + + + +1568 + +qos-start +file + + + + +2013-03-17T12:13:19.000000Z +9418edd146e30aead985459b915b568e +2007-04-06T16:59:56.568018Z +6875 +nbd +has-props + + + + + + + + + + + + + + + + + + + + +55 + diff --git a/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-start.svn-base b/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-start.svn-base new file mode 100644 index 0000000..03b5bfa --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-start.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:eol-style +V 6 +native +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-stat.svn-base b/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-stat.svn-base new file mode 100644 index 0000000..03b5bfa --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-stat.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:eol-style +V 6 +native +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-stop.svn-base b/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-stop.svn-base new file mode 100644 index 0000000..03b5bfa --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/.svn/prop-base/qos-stop.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:eol-style +V 6 +native +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-start.svn-base b/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-start.svn-base new file mode 100644 index 0000000..261ffb4 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-start.svn-base @@ -0,0 +1,4 @@ +#!/bin/sh +qos-stop +/usr/lib/qos/generate.sh all | sh + diff --git a/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-stat.svn-base b/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-stat.svn-base new file mode 100644 index 0000000..78d1638 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-stat.svn-base @@ -0,0 +1,67 @@ +#!/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 +} + +config_cb() { + config_get TYPE "$CONFIG_SECTION" TYPE + [ "interface" == "$TYPE" ] && { + config_get device "$CONFIG_SECTION" ifname + [ -z "$device" ] && device="$(get_ifname ${CONFIG_SECTION})" + config_set "$CONFIG_SECTION" device "$device" + } +} + +config_load qos + +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" diff --git a/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-stop.svn-base b/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-stop.svn-base new file mode 100644 index 0000000..7f654d8 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/.svn/text-base/qos-stop.svn-base @@ -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 diff --git a/package/network/config/qos-scripts/files/usr/bin/qos-start b/package/network/config/qos-scripts/files/usr/bin/qos-start new file mode 100755 index 0000000..261ffb4 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/qos-start @@ -0,0 +1,4 @@ +#!/bin/sh +qos-stop +/usr/lib/qos/generate.sh all | sh + diff --git a/package/network/config/qos-scripts/files/usr/bin/qos-stat b/package/network/config/qos-scripts/files/usr/bin/qos-stat new file mode 100755 index 0000000..78d1638 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/qos-stat @@ -0,0 +1,67 @@ +#!/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 +} + +config_cb() { + config_get TYPE "$CONFIG_SECTION" TYPE + [ "interface" == "$TYPE" ] && { + config_get device "$CONFIG_SECTION" ifname + [ -z "$device" ] && device="$(get_ifname ${CONFIG_SECTION})" + config_set "$CONFIG_SECTION" device "$device" + } +} + +config_load qos + +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" diff --git a/package/network/config/qos-scripts/files/usr/bin/qos-stop b/package/network/config/qos-scripts/files/usr/bin/qos-stop new file mode 100755 index 0000000..7f654d8 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/bin/qos-stop @@ -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 diff --git a/package/network/config/qos-scripts/files/usr/lib/.svn/entries b/package/network/config/qos-scripts/files/usr/lib/.svn/entries new file mode 100644 index 0000000..5b8d750 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/lib/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/usr/lib +svn://svn.openwrt.org/openwrt + + + +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +qos +dir + diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/.svn/entries b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/entries new file mode 100644 index 0000000..3fb7b83 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/qos-scripts/files/usr/lib/qos +svn://svn.openwrt.org/openwrt + + + +2012-06-05T16:04:23.055438Z +32062 +jow + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +tcrules.awk +file + + + + +2013-03-17T12:13:19.000000Z +82d952dc6351afe17daf1a4b70d3d283 +2012-05-16T15:23:16.119139Z +31759 +nbd + + + + + + + + + + + + + + + + + + + + + +2081 + +generate.sh +file + + + + +2013-03-17T12:13:19.000000Z +dc4f29f95d07a2ad931ae0d5d4c8b7f9 +2012-06-05T16:04:23.055438Z +32062 +jow +has-props + + + + + + + + + + + + + + + + + + + + +13106 + diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/.svn/prop-base/generate.sh.svn-base b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/prop-base/generate.sh.svn-base new file mode 100644 index 0000000..03b5bfa --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/prop-base/generate.sh.svn-base @@ -0,0 +1,9 @@ +K 13 +svn:eol-style +V 6 +native +K 14 +svn:executable +V 1 +* +END diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/.svn/text-base/generate.sh.svn-base b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/text-base/generate.sh.svn-base new file mode 100644 index 0000000..440b43f --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/text-base/generate.sh.svn-base @@ -0,0 +1,497 @@ +#!/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/0xff";; + default) pkt=1; append "$var" "-m mark --mark 0/0xff";; + 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" + ;; + *:layer7) + add_insmod ipt_layer7 + add_insmod xt_layer7 + append "$var" "-m layer7 --l7proto $value${pkt:+ --l7pkt}" + ;; + *: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 ipt_connbytes + append "$var" "-m connbytes --connbytes $value --connbytes-dir both --connbytes-mode bytes" + ;; + *:tos) + add_insmod ipt_tos + case "$value" in + !*) append "$var" "-m tos ! --tos $value";; + *) append "$var" "-m tos --tos $value" + esac + ;; + *:dscp) + add_insmod ipt_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 + ;; + 1:pktsize) + value="$(echo "$value" | sed -e 's,-,:,g')" + add_insmod ipt_length + append "$var" "-m length --length $value" + ;; + 1:limit) + add_insmod ipt_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/0xff";; + *) append "$var" "-m mark --mark $class/0xff";; + esac + ;; + 1:TOS) + add_insmod ipt_TOS + config_get TOS "$rule" 'TOS' + suffix="-j TOS --set-tos "${TOS:-"Normal-Service"} + ;; + 1:DSCP) + add_insmod ipt_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 + } + + # Section start + case "$1" in + interface) + config_set "$2" "classgroup" "Default" + config_set "$2" "upload" "128" + ;; + classify|default|reclassify) + option_cb() { + append options "$1" + } + ;; + esac + + # Section end + config_get TYPE "$CONFIG_SECTION" TYPE + case "$TYPE" in + interface) + config_get_bool enabled "$CONFIG_SECTION" enabled 1 + [ 1 -eq "$enabled" ] || return 0 + config_get classgroup "$CONFIG_SECTION" classgroup + config_set "$CONFIG_SECTION" ifbdev "$C" + C=$(($C+1)) + append INTERFACES "$CONFIG_SECTION" + config_set "$classgroup" enabled 1 + config_get device "$CONFIG_SECTION" device + [ -z "$device" ] && { + device="$(find_ifname ${CONFIG_SECTION})" + config_set "$CONFIG_SECTION" device "${device:-eth0}" + } + ;; + classgroup) append CG "$CONFIG_SECTION";; + classify|default|reclassify) + case "$TYPE" in + classify) var="ctrules";; + *) var="rules";; + esac + config_get target "$CONFIG_SECTION" target + config_set "$CONFIG_SECTION" options "$options" + append "$var" "$CONFIG_SECTION" + unset options + ;; + 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" \ + -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 txqueuelen 5 >&- 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: protocol ip 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: protocol ip 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 + add_insmod sch_fq_codel + + 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 ipt_DSCP + parse_matching_rule iptrule "$rule" "$s_options" "$prefix" "-j DSCP --set-dscp 0" + append "$var" "$iptrule" "$N" + unset iptrule + } + + 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" + add_rules iptrules "$ctrules" "iptables -t mangle -A qos_${cg}_ct" + 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 ipt_length + append pktrules "iptables -t mangle -A qos_${cg} -m mark --mark $mark/0xff -m length --length $maxsize: -j MARK --set-mark 0/0xff" "$N" + } + done + add_rules pktrules "$rules" "iptables -t mangle -A qos_${cg}" + 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}}" + append up "iptables -t mangle -A OUTPUT -o $device -j qos_${cg}" "$N" + append up "iptables -t mangle -A FORWARD -o $device -j qos_${cg}" "$N" + done + cat <<EOF +$INSMOD +iptables -t mangle -N qos_${cg} >&- 2>&- +iptables -t mangle -N qos_${cg}_ct >&- 2>&- +${iptrules:+${iptrules}${N}iptables -t mangle -A qos_${cg}_ct -j CONNMARK --save-mark --mask 0xff} +iptables -t mangle -A qos_${cg} -j CONNMARK --restore-mark --mask 0xff +iptables -t mangle -A qos_${cg} -m mark --mark 0/0xff -j qos_${cg}_ct +$pktrules +$up$N${down:+${down}$N} +EOF + unset INSMOD +} + +start_firewall() { + add_insmod ipt_multiport + add_insmod ipt_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 + iptables -t mangle -S | + # Find rules for the qos_* chains + grep '^-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/^./iptables -t mangle &/p' +} + +C="0" +INTERFACES="" +[ -e ./qos.conf ] && { + . ./qos.conf + config_cb +} || config_load qos + +C="0" +for iface in $INTERFACES; do + export C="$(($C + 1))" +done + +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 diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/.svn/text-base/tcrules.awk.svn-base b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/text-base/tcrules.awk.svn-base new file mode 100644 index 0000000..a19b651 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/lib/qos/.svn/text-base/tcrules.awk.svn-base @@ -0,0 +1,95 @@ +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" + } + + # filter rule + for (i = 1; i <= n; i++) { + print "tc filter add dev "device" parent 1: prio "class[i]" protocol ip handle "class[i]"/0xff fw flowid 1:"class[i] "0" + filterc=1 + if (filter[i] != "") { + print " tc filter add dev "device" parent "class[i]"00: handle "filterc"0 "filter[i] + filterc=filterc+1 + } + } +} + diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh b/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh new file mode 100755 index 0000000..440b43f --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh @@ -0,0 +1,497 @@ +#!/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/0xff";; + default) pkt=1; append "$var" "-m mark --mark 0/0xff";; + 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" + ;; + *:layer7) + add_insmod ipt_layer7 + add_insmod xt_layer7 + append "$var" "-m layer7 --l7proto $value${pkt:+ --l7pkt}" + ;; + *: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 ipt_connbytes + append "$var" "-m connbytes --connbytes $value --connbytes-dir both --connbytes-mode bytes" + ;; + *:tos) + add_insmod ipt_tos + case "$value" in + !*) append "$var" "-m tos ! --tos $value";; + *) append "$var" "-m tos --tos $value" + esac + ;; + *:dscp) + add_insmod ipt_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 + ;; + 1:pktsize) + value="$(echo "$value" | sed -e 's,-,:,g')" + add_insmod ipt_length + append "$var" "-m length --length $value" + ;; + 1:limit) + add_insmod ipt_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/0xff";; + *) append "$var" "-m mark --mark $class/0xff";; + esac + ;; + 1:TOS) + add_insmod ipt_TOS + config_get TOS "$rule" 'TOS' + suffix="-j TOS --set-tos "${TOS:-"Normal-Service"} + ;; + 1:DSCP) + add_insmod ipt_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 + } + + # Section start + case "$1" in + interface) + config_set "$2" "classgroup" "Default" + config_set "$2" "upload" "128" + ;; + classify|default|reclassify) + option_cb() { + append options "$1" + } + ;; + esac + + # Section end + config_get TYPE "$CONFIG_SECTION" TYPE + case "$TYPE" in + interface) + config_get_bool enabled "$CONFIG_SECTION" enabled 1 + [ 1 -eq "$enabled" ] || return 0 + config_get classgroup "$CONFIG_SECTION" classgroup + config_set "$CONFIG_SECTION" ifbdev "$C" + C=$(($C+1)) + append INTERFACES "$CONFIG_SECTION" + config_set "$classgroup" enabled 1 + config_get device "$CONFIG_SECTION" device + [ -z "$device" ] && { + device="$(find_ifname ${CONFIG_SECTION})" + config_set "$CONFIG_SECTION" device "${device:-eth0}" + } + ;; + classgroup) append CG "$CONFIG_SECTION";; + classify|default|reclassify) + case "$TYPE" in + classify) var="ctrules";; + *) var="rules";; + esac + config_get target "$CONFIG_SECTION" target + config_set "$CONFIG_SECTION" options "$options" + append "$var" "$CONFIG_SECTION" + unset options + ;; + 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" \ + -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 txqueuelen 5 >&- 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: protocol ip 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: protocol ip 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 + add_insmod sch_fq_codel + + 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 ipt_DSCP + parse_matching_rule iptrule "$rule" "$s_options" "$prefix" "-j DSCP --set-dscp 0" + append "$var" "$iptrule" "$N" + unset iptrule + } + + 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" + add_rules iptrules "$ctrules" "iptables -t mangle -A qos_${cg}_ct" + 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 ipt_length + append pktrules "iptables -t mangle -A qos_${cg} -m mark --mark $mark/0xff -m length --length $maxsize: -j MARK --set-mark 0/0xff" "$N" + } + done + add_rules pktrules "$rules" "iptables -t mangle -A qos_${cg}" + 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}}" + append up "iptables -t mangle -A OUTPUT -o $device -j qos_${cg}" "$N" + append up "iptables -t mangle -A FORWARD -o $device -j qos_${cg}" "$N" + done + cat <<EOF +$INSMOD +iptables -t mangle -N qos_${cg} >&- 2>&- +iptables -t mangle -N qos_${cg}_ct >&- 2>&- +${iptrules:+${iptrules}${N}iptables -t mangle -A qos_${cg}_ct -j CONNMARK --save-mark --mask 0xff} +iptables -t mangle -A qos_${cg} -j CONNMARK --restore-mark --mask 0xff +iptables -t mangle -A qos_${cg} -m mark --mark 0/0xff -j qos_${cg}_ct +$pktrules +$up$N${down:+${down}$N} +EOF + unset INSMOD +} + +start_firewall() { + add_insmod ipt_multiport + add_insmod ipt_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 + iptables -t mangle -S | + # Find rules for the qos_* chains + grep '^-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/^./iptables -t mangle &/p' +} + +C="0" +INTERFACES="" +[ -e ./qos.conf ] && { + . ./qos.conf + config_cb +} || config_load qos + +C="0" +for iface in $INTERFACES; do + export C="$(($C + 1))" +done + +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 diff --git a/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk b/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk new file mode 100644 index 0000000..a19b651 --- /dev/null +++ b/package/network/config/qos-scripts/files/usr/lib/qos/tcrules.awk @@ -0,0 +1,95 @@ +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" + } + + # filter rule + for (i = 1; i <= n; i++) { + print "tc filter add dev "device" parent 1: prio "class[i]" protocol ip handle "class[i]"/0xff fw flowid 1:"class[i] "0" + filterc=1 + if (filter[i] != "") { + print " tc filter add dev "device" parent "class[i]"00: handle "filterc"0 "filter[i] + filterc=filterc+1 + } + } +} + diff --git a/package/network/config/soloscli/.svn/entries b/package/network/config/soloscli/.svn/entries new file mode 100644 index 0000000..a0a97d4 --- /dev/null +++ b/package/network/config/soloscli/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/soloscli +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +patches +dir + +Makefile +file + + + + +2013-03-17T12:13:21.000000Z +9f83905a4b148adefe46725583d2257e +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +1155 + diff --git a/package/network/config/soloscli/.svn/text-base/Makefile.svn-base b/package/network/config/soloscli/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..9a7cd89 --- /dev/null +++ b/package/network/config/soloscli/.svn/text-base/Makefile.svn-base @@ -0,0 +1,45 @@ +# +# Copyright (C) 2006-2011 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:=0.11 +PKG_RELEASE:=3 + +PKG_SOURCE:=solos-pci-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/openadsl +PKG_MD5SUM:=ab3f3fa654ef7c3a402980eca094e690 + +PKG_INSTALL:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/solos-pci-$(PKG_VERSION) + +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)) diff --git a/package/network/config/soloscli/Makefile b/package/network/config/soloscli/Makefile new file mode 100644 index 0000000..9a7cd89 --- /dev/null +++ b/package/network/config/soloscli/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2006-2011 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:=0.11 +PKG_RELEASE:=3 + +PKG_SOURCE:=solos-pci-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/openadsl +PKG_MD5SUM:=ab3f3fa654ef7c3a402980eca094e690 + +PKG_INSTALL:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/solos-pci-$(PKG_VERSION) + +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)) diff --git a/package/network/config/soloscli/files/.svn/entries b/package/network/config/soloscli/files/.svn/entries new file mode 100644 index 0000000..c4ee455 --- /dev/null +++ b/package/network/config/soloscli/files/.svn/entries @@ -0,0 +1,65 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/soloscli/files +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +solos-log-stats +file + + + + +2013-03-17T12:13:21.000000Z +8d361d780cc0529ec18113bbf657b51f +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +606 + +etc +dir + diff --git a/package/network/config/soloscli/files/.svn/text-base/solos-log-stats.svn-base b/package/network/config/soloscli/files/.svn/text-base/solos-log-stats.svn-base new file mode 100644 index 0000000..2b75ee3 --- /dev/null +++ b/package/network/config/soloscli/files/.svn/text-base/solos-log-stats.svn-base @@ -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 + diff --git a/package/network/config/soloscli/files/etc/.svn/entries b/package/network/config/soloscli/files/etc/.svn/entries new file mode 100644 index 0000000..32d58cf --- /dev/null +++ b/package/network/config/soloscli/files/etc/.svn/entries @@ -0,0 +1,34 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/soloscli/files/etc +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +uci-default +dir + +hotplug.d +dir + diff --git a/package/network/config/soloscli/files/etc/hotplug.d/.svn/entries b/package/network/config/soloscli/files/etc/hotplug.d/.svn/entries new file mode 100644 index 0000000..7bf0858 --- /dev/null +++ b/package/network/config/soloscli/files/etc/hotplug.d/.svn/entries @@ -0,0 +1,31 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/soloscli/files/etc/hotplug.d +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +atm +dir + diff --git a/package/network/config/soloscli/files/etc/hotplug.d/atm/.svn/entries b/package/network/config/soloscli/files/etc/hotplug.d/atm/.svn/entries new file mode 100644 index 0000000..74fbce0 --- /dev/null +++ b/package/network/config/soloscli/files/etc/hotplug.d/atm/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/soloscli/files/etc/hotplug.d/atm +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +15-solos-init +file + + + + +2013-03-17T12:13:21.000000Z +08421ddd0319f1c50cbdbad55e77de72 +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +483 + diff --git a/package/network/config/soloscli/files/etc/hotplug.d/atm/.svn/text-base/15-solos-init.svn-base b/package/network/config/soloscli/files/etc/hotplug.d/atm/.svn/text-base/15-solos-init.svn-base new file mode 100644 index 0000000..36d13ea --- /dev/null +++ b/package/network/config/soloscli/files/etc/hotplug.d/atm/.svn/text-base/15-solos-init.svn-base @@ -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 diff --git a/package/network/config/soloscli/files/etc/hotplug.d/atm/15-solos-init b/package/network/config/soloscli/files/etc/hotplug.d/atm/15-solos-init new file mode 100644 index 0000000..36d13ea --- /dev/null +++ b/package/network/config/soloscli/files/etc/hotplug.d/atm/15-solos-init @@ -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 diff --git a/package/network/config/soloscli/files/etc/uci-default/.svn/entries b/package/network/config/soloscli/files/etc/uci-default/.svn/entries new file mode 100644 index 0000000..a19d58d --- /dev/null +++ b/package/network/config/soloscli/files/etc/uci-default/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/soloscli/files/etc/uci-default +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +solos +file + + + + +2013-03-17T12:13:21.000000Z +ca2ddd654342ee71329652f4344aa397 +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +384 + diff --git a/package/network/config/soloscli/files/etc/uci-default/.svn/text-base/solos.svn-base b/package/network/config/soloscli/files/etc/uci-default/.svn/text-base/solos.svn-base new file mode 100644 index 0000000..7f69da6 --- /dev/null +++ b/package/network/config/soloscli/files/etc/uci-default/.svn/text-base/solos.svn-base @@ -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__ diff --git a/package/network/config/soloscli/files/etc/uci-default/solos b/package/network/config/soloscli/files/etc/uci-default/solos new file mode 100644 index 0000000..7f69da6 --- /dev/null +++ b/package/network/config/soloscli/files/etc/uci-default/solos @@ -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__ diff --git a/package/network/config/soloscli/files/solos-log-stats b/package/network/config/soloscli/files/solos-log-stats new file mode 100644 index 0000000..2b75ee3 --- /dev/null +++ b/package/network/config/soloscli/files/solos-log-stats @@ -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 + diff --git a/package/network/config/soloscli/patches/.svn/entries b/package/network/config/soloscli/patches/.svn/entries new file mode 100644 index 0000000..0d1d9d9 --- /dev/null +++ b/package/network/config/soloscli/patches/.svn/entries @@ -0,0 +1,96 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/soloscli/patches +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +000-Makefile.patch +file + + + + +2013-03-17T12:13:21.000000Z +7c037e1d94d88b05963028db355c379f +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +429 + +001-newline.patch +file + + + + +2013-03-17T12:13:21.000000Z +8e93d05cb136c095354595245f252f0c +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +327 + diff --git a/package/network/config/soloscli/patches/.svn/text-base/000-Makefile.patch.svn-base b/package/network/config/soloscli/patches/.svn/text-base/000-Makefile.patch.svn-base new file mode 100644 index 0000000..914d6d8 --- /dev/null +++ b/package/network/config/soloscli/patches/.svn/text-base/000-Makefile.patch.svn-base @@ -0,0 +1,21 @@ +--- a/Makefile 2010-06-14 14:17:11.000000000 +1000 ++++ b/Makefile 2010-06-14 14:17:54.000000000 +1000 +@@ -13,6 +13,11 @@ + KDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + ++soloscli/soloscli: ++ $(MAKE) -C soloscli ++ ++install: ++ + default: + $(MAKE) -C $(KDIR) M=$(PWD) modules + +@@ -20,5 +25,6 @@ + rm -f *.o *.ko *.mod.c .*.cmd + rm -rf .tmp_versions + rm -f Module.symvers ++ $(MAKE) -C soloscli clean + + endif diff --git a/package/network/config/soloscli/patches/.svn/text-base/001-newline.patch.svn-base b/package/network/config/soloscli/patches/.svn/text-base/001-newline.patch.svn-base new file mode 100644 index 0000000..4b663e8 --- /dev/null +++ b/package/network/config/soloscli/patches/.svn/text-base/001-newline.patch.svn-base @@ -0,0 +1,15 @@ +--- a/soloscli/soloscli.c ++++ b/soloscli/soloscli.c +@@ -238,7 +238,11 @@ + } + if (strcmp(buf,pid) == 0) { + /* printf("Sequence matches.\n"); */ +- printf("%s",bufp); ++ if(buf[(len-1)] == '\n'){ ++ printf("%s",bufp); ++ } else { ++ printf("%s\n",bufp); ++ } + } else { + printf("Sequence incorrect.\n"); + buf[i] = '\n'; diff --git a/package/network/config/soloscli/patches/000-Makefile.patch b/package/network/config/soloscli/patches/000-Makefile.patch new file mode 100644 index 0000000..914d6d8 --- /dev/null +++ b/package/network/config/soloscli/patches/000-Makefile.patch @@ -0,0 +1,21 @@ +--- a/Makefile 2010-06-14 14:17:11.000000000 +1000 ++++ b/Makefile 2010-06-14 14:17:54.000000000 +1000 +@@ -13,6 +13,11 @@ + KDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + ++soloscli/soloscli: ++ $(MAKE) -C soloscli ++ ++install: ++ + default: + $(MAKE) -C $(KDIR) M=$(PWD) modules + +@@ -20,5 +25,6 @@ + rm -f *.o *.ko *.mod.c .*.cmd + rm -rf .tmp_versions + rm -f Module.symvers ++ $(MAKE) -C soloscli clean + + endif diff --git a/package/network/config/soloscli/patches/001-newline.patch b/package/network/config/soloscli/patches/001-newline.patch new file mode 100644 index 0000000..4b663e8 --- /dev/null +++ b/package/network/config/soloscli/patches/001-newline.patch @@ -0,0 +1,15 @@ +--- a/soloscli/soloscli.c ++++ b/soloscli/soloscli.c +@@ -238,7 +238,11 @@ + } + if (strcmp(buf,pid) == 0) { + /* printf("Sequence matches.\n"); */ +- printf("%s",bufp); ++ if(buf[(len-1)] == '\n'){ ++ printf("%s",bufp); ++ } else { ++ printf("%s\n",bufp); ++ } + } else { + printf("Sequence incorrect.\n"); + buf[i] = '\n'; diff --git a/package/network/config/swconfig/.svn/entries b/package/network/config/swconfig/.svn/entries new file mode 100644 index 0000000..4cc868a --- /dev/null +++ b/package/network/config/swconfig/.svn/entries @@ -0,0 +1,68 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/swconfig +svn://svn.openwrt.org/openwrt + + + +2012-12-14T12:11:50.852722Z +34679 +juhosg + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +files +dir + +src +dir + +Makefile +file + + + + +2013-03-17T12:13:19.000000Z +c11bf221290c35e4f3c8a321b186137b +2012-12-14T12:11:50.852722Z +34679 +juhosg + + + + + + + + + + + + + + + + + + + + + +1125 + diff --git a/package/network/config/swconfig/.svn/text-base/Makefile.svn-base b/package/network/config/swconfig/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..76817f0 --- /dev/null +++ b/package/network/config/swconfig/.svn/text-base/Makefile.svn-base @@ -0,0 +1,49 @@ +# +# 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:=10 + +PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org> + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/swconfig + SECTION:=base + CATEGORY:=Base system + DEPENDS:=@!TARGET_brcm47xx +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) + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + LIBS="$(TARGET_LDFLAGS) -lnl-tiny -lm -luci" +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)) diff --git a/package/network/config/swconfig/Makefile b/package/network/config/swconfig/Makefile new file mode 100644 index 0000000..76817f0 --- /dev/null +++ b/package/network/config/swconfig/Makefile @@ -0,0 +1,49 @@ +# +# 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:=10 + +PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org> + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/swconfig + SECTION:=base + CATEGORY:=Base system + DEPENDS:=@!TARGET_brcm47xx +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) + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \ + $(MAKE) -C $(PKG_BUILD_DIR) \ + $(TARGET_CONFIGURE_OPTS) \ + LIBS="$(TARGET_LDFLAGS) -lnl-tiny -lm -luci" +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)) diff --git a/package/network/config/swconfig/files/.svn/entries b/package/network/config/swconfig/files/.svn/entries new file mode 100644 index 0000000..348abda --- /dev/null +++ b/package/network/config/swconfig/files/.svn/entries @@ -0,0 +1,62 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/swconfig/files +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +switch.sh +file + + + + +2013-03-17T12:13:19.000000Z +b244d1648b8c524d8945430721f1e61f +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +284 + diff --git a/package/network/config/swconfig/files/.svn/text-base/switch.sh.svn-base b/package/network/config/swconfig/files/.svn/text-base/switch.sh.svn-base new file mode 100644 index 0000000..18d5fbd --- /dev/null +++ b/package/network/config/swconfig/files/.svn/text-base/switch.sh.svn-base @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright (C) 2009 OpenWrt.org + +setup_switch_dev() { + config_get name "$1" name + name="${name:-$1}" + [ -d "/sys/class/net/$name" ] && ifconfig "$name" up + swconfig dev "$name" load network +} + +setup_switch() { + config_load network + config_foreach setup_switch_dev switch +} diff --git a/package/network/config/swconfig/files/switch.sh b/package/network/config/swconfig/files/switch.sh new file mode 100644 index 0000000..18d5fbd --- /dev/null +++ b/package/network/config/swconfig/files/switch.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# Copyright (C) 2009 OpenWrt.org + +setup_switch_dev() { + config_get name "$1" name + name="${name:-$1}" + [ -d "/sys/class/net/$name" ] && ifconfig "$name" up + swconfig dev "$name" load network +} + +setup_switch() { + config_load network + config_foreach setup_switch_dev switch +} diff --git a/package/network/config/swconfig/src/.svn/entries b/package/network/config/swconfig/src/.svn/entries new file mode 100644 index 0000000..e4c62fe --- /dev/null +++ b/package/network/config/swconfig/src/.svn/entries @@ -0,0 +1,198 @@ +10 + +dir +36060 +svn://svn.openwrt.org/openwrt/trunk/package/network/config/swconfig/src +svn://svn.openwrt.org/openwrt + + + +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + +3c298f89-4303-0410-b956-a3cf2f4a3e73 + +swlib.c +file + + + + +2013-03-17T12:13:19.000000Z +f330c4f9a949bca067af5461f44ad641 +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +13642 + +uci.c +file + + + + +2013-03-17T12:13:19.000000Z +25ab718228809f280e76d88db3413909 +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +5625 + +swlib.h +file + + + + +2013-03-17T12:13:19.000000Z +df4c8993cd40723d9b4b8368a2fa9a0e +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +6327 + +cli.c +file + + + + +2013-03-17T12:13:19.000000Z +3846fc5eac83531d6e9a778e3ff99f06 +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +6861 + +Makefile +file + + + + +2013-03-17T12:13:19.000000Z +ce9e6e4c852401621f773c0249b6bfb9 +2012-10-17T22:45:58.668189Z +33830 +blogic + + + + + + + + + + + + + + + + + + + + + +186 + diff --git a/package/network/config/swconfig/src/.svn/text-base/Makefile.svn-base b/package/network/config/swconfig/src/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..0d56f43 --- /dev/null +++ b/package/network/config/swconfig/src/.svn/text-base/Makefile.svn-base @@ -0,0 +1,12 @@ +ifndef CFLAGS +CFLAGS = -O2 -g -I ../src +endif +LIBS=-lnl -lnl-genl + +all: swconfig + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $^ + +swconfig: cli.o swlib.o uci.o + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) diff --git a/package/network/config/swconfig/src/.svn/text-base/cli.c.svn-base b/package/network/config/swconfig/src/.svn/text-base/cli.c.svn-base new file mode 100644 index 0000000..9cd16ab --- /dev/null +++ b/package/network/config/swconfig/src/.svn/text-base/cli.c.svn-base @@ -0,0 +1,340 @@ +/* + * swconfig.c: Switch configuration utility + * + * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> + * 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, +}; + +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 void +print_attr_val(const struct switch_attr *attr, const struct switch_val *val) +{ + 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; + 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 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; + struct uci_element *e; + 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 err; + int i; + + int cmd = CMD_NONE; + char *cdev = NULL; + int cport = -1; + int cvlan = -1; + char *ckey = NULL; + char *cvalue = NULL; + + 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, "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\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); + goto out; + } + } + + switch(cmd) + { + case CMD_SET: + if ((a->type != SWITCH_TYPE_NOVAL) && + (cvalue == NULL)) + print_usage(); + + if(cvlan > -1) + cport = cvlan; + + if(swlib_set_attr_string(dev, a, cport, cvalue) < 0) + { + fprintf(stderr, "failed\n"); + retval = -1; + goto out; + } + break; + case CMD_GET: + if(cvlan > -1) + val.port_vlan = cvlan; + if(cport > -1) + val.port_vlan = cport; + if(swlib_get_attr(dev, a, &val) < 0) + { + fprintf(stderr, "failed\n"); + retval = -1; + 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_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 0; +} diff --git a/package/network/config/swconfig/src/.svn/text-base/swlib.c.svn-base b/package/network/config/swconfig/src/.svn/text-base/swlib.c.svn-base new file mode 100644 index 0000000..de08717 --- /dev/null +++ b/package/network/config/swconfig/src/.svn/text-base/swlib.c.svn-base @@ -0,0 +1,686 @@ +/* + * swlib.c: Switch configuration API (user space part) + * + * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> + * + * 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_PORT_ID] = { .type = NLA_U32 }, + [SWITCH_PORT_FLAG_TAGGED] = { .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; + + 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) { + if (data(msg, arg) < 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_val(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct switch_val *val = arg; + struct switch_attr *attr = val->attr; + + 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); + + 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_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; + 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); +} + +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_val val; + char *ptr; + + 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 = 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_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 (cache) + nl_cache_free(cache); + if (handle) + nl_socket_free(handle); + 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_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 (!sa->head) { + sa->head = dev; + sa->ptr = dev; + } else { + sa->ptr->next = dev; + sa->ptr = dev; + } + + refcount++; +done: + return NL_SKIP; +} + + +struct switch_dev * +swlib_connect(const char *name) +{ + struct swlib_scan_arg arg; + int err; + + 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); + a = next; + } + *head = NULL; +} + +void +swlib_free(struct switch_dev *dev) +{ + swlib_free_attributes(&dev->ops); + swlib_free_attributes(&dev->port_ops); + swlib_free_attributes(&dev->vlan_ops); + 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; + } +} diff --git a/package/network/config/swconfig/src/.svn/text-base/swlib.h.svn-base b/package/network/config/swconfig/src/.svn/text-base/swlib.h.svn-base new file mode 100644 index 0000000..ff73969 --- /dev/null +++ b/package/network/config/swconfig/src/.svn/text-base/swlib.h.svn-base @@ -0,0 +1,234 @@ +/* + * swlib.h: Switch configuration API (user space part) + * + * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org> + * + * 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), +}; + + +struct switch_dev; +struct switch_attr; +struct switch_port; +struct switch_val; +struct uci_package; + +struct switch_dev { + int id; + char dev_name[IFNAMSIZ]; + const char *name; + const 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_dev *next; + void *priv; +}; + +struct switch_val { + struct switch_attr *attr; + int len; + int err; + int port_vlan; + union { + const char *s; + int i; + struct switch_port *ports; + } value; +}; + +struct switch_attr { + struct switch_dev *dev; + int atype; + int id; + int type; + const char *name; + const char *description; + struct switch_attr *next; +}; + +struct switch_port { + unsigned int id; + unsigned int flags; +}; + +/** + * 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 diff --git a/package/network/config/swconfig/src/.svn/text-base/uci.c.svn-base b/package/network/config/swconfig/src/.svn/text-base/uci.c.svn-base new file mode 100644 index 0000000..893e3d1 --- /dev/null +++ b/package/network/config/swconfig/src/.svn/text-base/uci.c.svn-base @@ -0,0 +1,248 @@ +/* + * uci.c: UCI binding for the switch configuration utility + * + * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> + * + * 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 int +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; + int i; + + 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_context *ctx = p->ctx; + 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, *port, *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, *vlan, *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; +} diff --git a/package/network/config/swconfig/src/Makefile b/package/network/config/swconfig/src/Makefile new file mode 100644 index 0000000..0d56f43 --- /dev/null +++ b/package/network/config/swconfig/src/Makefile @@ -0,0 +1,12 @@ +ifndef CFLAGS +CFLAGS = -O2 -g -I ../src +endif +LIBS=-lnl -lnl-genl + +all: swconfig + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $^ + +swconfig: cli.o swlib.o uci.o + $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) diff --git a/package/network/config/swconfig/src/cli.c b/package/network/config/swconfig/src/cli.c new file mode 100644 index 0000000..9cd16ab --- /dev/null +++ b/package/network/config/swconfig/src/cli.c @@ -0,0 +1,340 @@ +/* + * swconfig.c: Switch configuration utility + * + * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> + * 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, +}; + +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 void +print_attr_val(const struct switch_attr *attr, const struct switch_val *val) +{ + 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; + 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 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; + struct uci_element *e; + 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 err; + int i; + + int cmd = CMD_NONE; + char *cdev = NULL; + int cport = -1; + int cvlan = -1; + char *ckey = NULL; + char *cvalue = NULL; + + 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, "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\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); + goto out; + } + } + + switch(cmd) + { + case CMD_SET: + if ((a->type != SWITCH_TYPE_NOVAL) && + (cvalue == NULL)) + print_usage(); + + if(cvlan > -1) + cport = cvlan; + + if(swlib_set_attr_string(dev, a, cport, cvalue) < 0) + { + fprintf(stderr, "failed\n"); + retval = -1; + goto out; + } + break; + case CMD_GET: + if(cvlan > -1) + val.port_vlan = cvlan; + if(cport > -1) + val.port_vlan = cport; + if(swlib_get_attr(dev, a, &val) < 0) + { + fprintf(stderr, "failed\n"); + retval = -1; + 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_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 0; +} diff --git a/package/network/config/swconfig/src/swlib.c b/package/network/config/swconfig/src/swlib.c new file mode 100644 index 0000000..de08717 --- /dev/null +++ b/package/network/config/swconfig/src/swlib.c @@ -0,0 +1,686 @@ +/* + * swlib.c: Switch configuration API (user space part) + * + * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org> + * + * 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_PORT_ID] = { .type = NLA_U32 }, + [SWITCH_PORT_FLAG_TAGGED] = { .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; + + 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) { + if (data(msg, arg) < 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_val(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct switch_val *val = arg; + struct switch_attr *attr = val->attr; + + 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); + + 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_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; + 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); +} + +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_val val; + char *ptr; + + 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 = 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_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 (cache) + nl_cache_free(cache); + if (handle) + nl_socket_free(handle); + 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_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 (!sa->head) { + sa->head = dev; + sa->ptr = dev; + } else { + sa->ptr->next = dev; + sa->ptr = dev; + } + + refcount++; +done: + return NL_SKIP; +} + + +struct switch_dev * +swlib_connect(const char *name) +{ + struct swlib_scan_arg arg; + int err; + + 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); + a = next; + } + *head = NULL; +} + +void +swlib_free(struct switch_dev *dev) +{ + swlib_free_attributes(&dev->ops); + swlib_free_attributes(&dev->port_ops); + swlib_free_attributes(&dev->vlan_ops); + 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; + } +} diff --git a/package/network/config/swconfig/src/swlib.h b/package/network/config/swconfig/src/swlib.h new file mode 100644 index 0000000..ff73969 --- /dev/null +++ b/package/network/config/swconfig/src/swlib.h @@ -0,0 +1,234 @@ +/* + * swlib.h: Switch configuration API (user space part) + * + * Copyright (C) 2008-2009 Felix Fietkau <nbd@openwrt.org> + * + * 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), +}; + + +struct switch_dev; +struct switch_attr; +struct switch_port; +struct switch_val; +struct uci_package; + +struct switch_dev { + int id; + char dev_name[IFNAMSIZ]; + const char *name; + const 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_dev *next; + void *priv; +}; + +struct switch_val { + struct switch_attr *attr; + int len; + int err; + int port_vlan; + union { + const char *s; + int i; + struct switch_port *ports; + } value; +}; + +struct switch_attr { + struct switch_dev *dev; + int atype; + int id; + int type; + const char *name; + const char *description; + struct switch_attr *next; +}; + +struct switch_port { + unsigned int id; + unsigned int flags; +}; + +/** + * 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 diff --git a/package/network/config/swconfig/src/uci.c b/package/network/config/swconfig/src/uci.c new file mode 100644 index 0000000..893e3d1 --- /dev/null +++ b/package/network/config/swconfig/src/uci.c @@ -0,0 +1,248 @@ +/* + * uci.c: UCI binding for the switch configuration utility + * + * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> + * + * 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 int +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; + int i; + + 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_context *ctx = p->ctx; + 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, *port, *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, *vlan, *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; +} |