From: Steven Barth Date: Tue, 15 Jan 2013 13:08:19 +0000 (+0000) Subject: ipv6-support: Switch to native IPv6 support X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=3235d860a6cb80a6c4fca264b70d88db3e223654;p=librecmc%2Flibrecmc.git ipv6-support: Switch to native IPv6 support SVN-Revision: 35174 --- diff --git a/package/network/ipv6/ipv6-support/Makefile b/package/network/ipv6/ipv6-support/Makefile index 74286e79b8..d3b397403d 100644 --- a/package/network/ipv6/ipv6-support/Makefile +++ b/package/network/ipv6/ipv6-support/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ipv6-support -PKG_VERSION:=2013-01-13 +PKG_VERSION:=2013-01-15 PKG_RELEASE:=1 include $(INCLUDE_DIR)/package.mk @@ -16,7 +16,7 @@ include $(INCLUDE_DIR)/package.mk define Package/ipv6-support SECTION:=ipv6 CATEGORY:=IPv6 - DEPENDS:=+kmod-ipv6 +6relayd +odhcp6c +6distributed +ip6tables +ubus + DEPENDS:=+kmod-ipv6 +6relayd +odhcp6c +ip6tables TITLE:=Basic IPv6-support for Customer Edge Routers MAINTAINER:=Steven Barth PKGARCH:=all @@ -33,21 +33,9 @@ endef define Build/Configure endef -define Package/ipv6-support/conffiles -/etc/config/network6 -endef - define Package/ipv6-support/install - $(INSTALL_DIR) $(1)/etc/hotplug.d/iface - $(INSTALL_DATA) ./files/ipv6.hotplug $(1)/etc/hotplug.d/iface/20-ipv6 - $(INSTALL_DIR) $(1)/lib/ipv6 - $(INSTALL_DATA) ./files/support.sh $(1)/lib/ipv6/support.sh - $(INSTALL_BIN) ./files/dhcpv6.sh $(1)/lib/ipv6/dhcpv6.sh - $(INSTALL_BIN) ./files/firewall.sh $(1)/lib/ipv6/firewall.sh - $(INSTALL_DIR) $(1)/etc/config - $(INSTALL_DATA) ./files/network6.config $(1)/etc/config/network6 $(INSTALL_DIR) $(1)/etc/uci-defaults - $(INSTALL_BIN) ./files/ipv6-support.defaults $(1)/etc/uci-defaults/ipv6-support.defaults + $(INSTALL_BIN) ./files/enable-ipv6.defaults $(1)/etc/uci-defaults/enable-ipv6 endef $(eval $(call BuildPackage,ipv6-support)) diff --git a/package/network/ipv6/ipv6-support/files/dhcpv6.sh b/package/network/ipv6/ipv6-support/files/dhcpv6.sh deleted file mode 100755 index 5a668cd9b1..0000000000 --- a/package/network/ipv6/ipv6-support/files/dhcpv6.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh -# Copyright (c) 2012 OpenWrt.org -. /lib/ipv6/support.sh -. /lib/netifd/netifd-proto.sh - -local device="$1" -local state="$2" -local network="" - -resolve_network network "$device" - -# Unknown network -[ -z "$network" ] && exit 0 - -if [ "$state" == "started" ]; then - # Start border - set_forward_border "$network" "$device" enable - - # Configure device - conf_set "$device" accept_ra 2 - conf_set "$device" forwarding 2 - - # Send RS on interface - [ -x /usr/sbin/6relayd ] && /usr/sbin/6relayd -s "$device" - - exit 0 -elif [ "$state" == "stopped" ]; then - # Deconfigure device - conf_set "$device" accept_ra 1 - conf_set "$device" forwarding 1 - - # Disable border - set_forward_border "$network" "$device" disable - - exit 0 -fi - -# Announce prefixes -for prefix in $PREFIXES; do - announce_prefix "$prefix" "$network" "$device" -done - -for prefix in $PREFIXES_LOST; do - announce_prefix "$prefix" "$network" "$device" delprefix -done - - -# Enable relaying if requested and we didn't get a prefix, disable otherwise -local fallback="stop" -[ -z "$PREFIXES" -a "$state" != "unbound" ] && fallback="start" -setup_prefix_fallback "$fallback" "$network" "$device" - - -# Operations in case of success -[ "$state" == "timeout" -o "$state" == "unbound" ] && exit 0 - -# Handshake completed, disable forwarding border -set_forward_border "$network" "$device" disable - -local peerdns -config_get_bool peerdns "$network" peerdns 1 -[ "$peerdns" -eq "1" ] && { - proto_init_update "*" 1 - proto_set_keep 1 - for server in $RDNSS; do - proto_add_dns_server "$server" - done - for domain in $DOMAINS; do - proto_add_dns_search "$domain" - done - proto_send_update "$network" -} - diff --git a/package/network/ipv6/ipv6-support/files/enable-ipv6.defaults b/package/network/ipv6/ipv6-support/files/enable-ipv6.defaults new file mode 100644 index 0000000000..c77914b530 --- /dev/null +++ b/package/network/ipv6/ipv6-support/files/enable-ipv6.defaults @@ -0,0 +1,11 @@ +#!/bin/sh +uci -q batch <<-EOF >/dev/null + set network.globals=globals + set network.globals.ula_prefix=auto + set network.wan6=interface + set network.wan6.proto=dhcpv6 + set network.wan6.ifname=@wan + set network.lan.ip6assign=64 + set network.wan.ipv6=1 + commit network +EOF diff --git a/package/network/ipv6/ipv6-support/files/firewall.sh b/package/network/ipv6/ipv6-support/files/firewall.sh deleted file mode 100755 index 57fcd382e9..0000000000 --- a/package/network/ipv6/ipv6-support/files/firewall.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -ip6tables -N ipv6-site-border -ip6tables -A forwarding_rule -s fc00::/7 -j ipv6-site-border -ip6tables -A forwarding_rule -d fc00::/7 -j ipv6-site-border - -mkdir -p /var/etc/ipv6-firewall.d -for i in /var/etc/ipv6-firewall.d/*; do - [ -f "$i" ] && . "$i" -done diff --git a/package/network/ipv6/ipv6-support/files/ipv6-support.defaults b/package/network/ipv6/ipv6-support/files/ipv6-support.defaults deleted file mode 100644 index 6a699a1453..0000000000 --- a/package/network/ipv6/ipv6-support/files/ipv6-support.defaults +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -uci -q batch <<-EOF >/dev/null - set firewall.ipv6_support=include - set firewall.ipv6_support.path=/lib/ipv6/firewall.sh - commit firewall -EOF diff --git a/package/network/ipv6/ipv6-support/files/ipv6.hotplug b/package/network/ipv6/ipv6-support/files/ipv6.hotplug deleted file mode 100644 index 52cdf3bde0..0000000000 --- a/package/network/ipv6/ipv6-support/files/ipv6.hotplug +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Copyright (c) 2012 OpenWrt.org -[ "$DEVICE" == "lo" ] && exit 0 -. /lib/ipv6/support.sh - -case "$ACTION" in - ifup) - enable_interface "$INTERFACE" "$DEVICE" - ;; - ifdown) - disable_interface "$INTERFACE" "$DEVICE" - ;; -esac diff --git a/package/network/ipv6/ipv6-support/files/network6.config b/package/network/ipv6/ipv6-support/files/network6.config deleted file mode 100644 index 37a327f2b2..0000000000 --- a/package/network/ipv6/ipv6-support/files/network6.config +++ /dev/null @@ -1,15 +0,0 @@ -config global global - option ula_prefix auto - -config interface wan - option mode dhcpv6 - option request_prefix auto - option prefix_fallback relay - option peerdns 1 - option site_border 1 - -config interface lan - option mode router - option advertise_prefix 64 - option relay_master wan - diff --git a/package/network/ipv6/ipv6-support/files/support.sh b/package/network/ipv6/ipv6-support/files/support.sh deleted file mode 100644 index 8ae803cf1c..0000000000 --- a/package/network/ipv6/ipv6-support/files/support.sh +++ /dev/null @@ -1,588 +0,0 @@ -#!/bin/sh -# Copyright (c) 2012 OpenWrt.org -. /lib/functions.sh -. /lib/functions/service.sh -. /lib/functions/network.sh - -config_load network6 -local NAT="ip6tables -t nat" - -conf_get() { - local __return="$1" - local __device="$2" - local __option="$3" - local __value=$(cat "/proc/sys/net/ipv6/conf/$__device/$__option") - eval "$__return=$__value" -} - - -conf_set() { - local device="$1" - local option="$2" - local value="$3" - echo "$value" > "/proc/sys/net/ipv6/conf/$device/$option" -} - - -stop_service() { - local __exe="$1" - SERVICE_PID_FILE="$2" - local __return="$3" - - service_check "$__exe" && { - service_stop "$__exe" - [ -n "$__return" ] && eval "$__return=1" - } - rm -f "$SERVICE_PID_FILE" -} - - -start_service() { - local cmd="$1" - local pidfile="$2" - - SERVICE_DAEMONIZE=1 - SERVICE_WRITE_PID=1 - SERVICE_PID_FILE="$pidfile" - service_start $cmd -} - - -resolve_network_add() { - local __section="$1" - local __device="$2" - local __return="$3" - local __cdevice - network_get_device __cdevice "$__section" - [ "$__cdevice" != "$__device" ] && return - - eval "$__return"'="'"$__section"'"' -} - - -resolve_network() { - local __return="$1" - local __device="$2" - config_foreach resolve_network_add interface "$__device" "$__return" -} - - -setup_masquerading() { - local cmd="$1" - local chain="network6_masquerade_$2" - local device="$3" - - $NAT -D POSTROUTING -j "$chain" 2>/dev/null && { - $NAT -F "$chain" 2>/dev/null - $NAT -X "$chain" 2>/dev/null - } - - [ "$cmd" != "stop" ] && { - $NAT -N "$chain" - $NAT -A "$chain" -o "$device" -j MASQUERADE - $NAT -A POSTROUTING -j "$chain" - } -} - - -setup_npt_chain() { - local cmd="$1" - local network="$2" - local chain="network6_npt_$network" - - [ "$cmd" != "start" ] && { - $NAT -D POSTROUTING -j "$chain" 2>/dev/null && { - $NAT -D PREROUTING -j "$chain" 2>/dev/null - $NAT -F "$chain" 2>/dev/null - $NAT -X "$chain" 2>/dev/null - } - } - - [ "$cmd" != "stop" ] && { - $NAT -N "$chain" 2>/dev/null && { - $NAT -A PREROUTING -j "$chain" - $NAT -A POSTROUTING -j "$chain" - } - } -} - - -announce_prefix() { - local prefix="$1" - local network="$2" - local device="$3" - local cmd="$4" - local type="$5" - - local addr=$(echo "$prefix" | cut -d/ -f1) - local rem=$(echo "$prefix" | cut -d/ -f2) - local length=$(echo "$rem" | cut -d, -f1) - local prefer="" - local valid="" - - # If preferred / valid provided - [ "$rem" != "$length" ] && { - prefer=$(echo "$rem" | cut -d, -f2) - valid=$(echo "$rem" | cut -d, -f3) - } - - # Get prefix configuration - local ula="" - local prefix_action="" - config_get ula global ula_prefix - config_get prefix_action "$network" prefix_action - [ -z "$prefix_action" ] && prefix_action="distribute" - - # Always announce the ULA when doing NPT - [ "$prefix" == "$ula" -a "$prefix_action" == "npt" ] && prefix_action="distribute" - - [ "$prefix_action" == "distribute" -o "$prefix_action" == "npt" ] && { - local msg='{"network": "'"$network"'", "prefix": "'"$addr"'", "length": '"$length" - [ -n "$valid" ] && msg="$msg"', "valid": '"$valid"', "preferred": '"$prefer" - [ -z "$cmd" ] && cmd=newprefix - - [ "$prefix_action" == "npt" ] && msg="$msg"', "npt": 1' - [ "$type" == "secondary" ] && msg="$msg"', "secondary": 1' - - # Detect MTU - local mtu - conf_get mtu "$device" mtu - msg="$msg"', "mtu": '"$mtu" - - ubus call 6distributed "$cmd" "$msg}" - } - - [ "$prefix_action" == "npt" ] && { - local chain="network6_npt_$network" - local ula_addr=$(echo "$ula" | cut -d/ -f1) - local ula_rem=$(echo "$ula" | cut -d/ -f2) - local ula_length=$(echo "$ula_rem" | cut -d, -f1) - local device="" - - network_get_device device "$network" - [ "$length" -lt "$ula_length" ] && length="$ula_length" - [ "$cmd" == "delprefix" ] && cmd="-D $chain" || cmd="-A $chain" - - local in="-i $device -d $addr/$length -j NETMAP --to $ula_addr/$ula_length" - local out="-o $device -s $ula_addr/$ula_length -j NETMAP --to $addr/$length" - - setup_npt_chain start "$network" - $NAT $cmd $in - $NAT $cmd $out - } -} - - -disable_router() { - local network="$1" - - # Notify the address distribution daemon - ubus call 6distributed deliface '{"network": "'"$network"'"}' - - - # Start RD & DHCPv6 service - local router_service - config_get router_service global router_service - - if [ "$router_service" == "dnsmasq" ]; then - rm -f "/var/etc/dnsmasq.d/ipv6-router-$network.conf" - /etc/init.d/dnsmasq restart - else - stop_service /usr/sbin/6relayd "/var/run/ipv6-router-$network.pid" - fi -} - - -restart_relay_slave() { - local __section="$1" - local __master="$2" - - network_is_up "$__section" || return - - local __device="" - network_get_device __device "$__section" - - local __cmaster="" - config_get __cmaster "$__section" relay_master - - [ "$__master" == "$__cmaster" ] && { - disable_interface "$__section" - enable_interface "$__section" "$__device" - } -} - - -add_relay_slave() { - local __section="$1" - local __return="$2" - local __master="$3" - local __mode="$4" - - network_is_up "$__section" || return - - # Get device - local __device="" - network_get_device __device "$__section" - - # Match master network - local __cmaster="" - config_get __cmaster "$__section" relay_master - [ "$__master" == "$__cmaster" ] || return - - # Test slave mode - local __cmode="" - config_get __cmode "$__section" mode - [ "$__cmode" == "downstream" ] && __cmode="router" - - # Don't start fallback interfaces if we are in forced-relay mode - [ "$__cmode" == "relay" -o "$__mode" == "fallback" ] || return - - # Don't make non-relay or non-router interfaces slaves - [ "$__cmode" == "relay" -o "$__cmode" == "router" ] || return - - # Disable any active distribution - [ "$__cmode" == "router" ] && disable_router "$__section" - - # Configure interface to accept RA and send RS - conf_set "$__device" accept_ra 2 - conf_set "$__device" forwarding 2 - - eval "$__return"'="$'"$__return"' '"$__device"'"' -} - - -stop_relay() { - local network="$1" - local pid_fallback="/var/run/ipv6-relay-fallback-$network.pid" - local pid_forced="/var/run/ipv6-relay-forced-$network.pid" - local was_fallback="" - - stop_service /usr/sbin/6relayd "$pid_fallback" was_fallback - stop_service /usr/sbin/6relayd "$pid_forced" - - # Reenable normal distribution on slave interfaces - [ -n "$was_fallback" ] && config_foreach restart_relay_slave interface "$network" -} - - -detect_forced_relay_mode() { - local __section="$1" - local __mode="$2" - - local __cmode - config_get __cmode "$__section" mode - [ "$__cmode" == "relay" ] && eval "$__mode=forced" -} - - -restart_relay() { - local network="$1" - local mode="$2" - - # Stop last active relay - stop_relay "$network" - - # Detect if we have a forced-relay - [ -z "$mode" ] && config_foreach detect_forced_relay_mode interface mode - - # Don't start without a mode - [ -z "$mode" ] && return - - # Detect master device - local device="" - network_get_device device "$network" - - # Generate command string - local cmd="/usr/sbin/6relayd -A $device" - local ifaces="" - config_foreach add_relay_slave interface ifaces "$network" "$mode" - - # Start relay - local pid="/var/run/ipv6-relay-$mode-$network.pid" - [ -n "$ifaces" ] && start_service "$cmd $ifaces" "$pid" - - # There are no slave interface, however indicate that we want to relay - [ -z "$ifaces" ] && touch "$pid" -} - - -setup_prefix_fallback() { - local cmd="$1" - local network="$2" - local device="$3" - - stop_relay "$network" - restart_relay "$network" - - setup_masquerading stop "$network" - - [ "$cmd" != "stop" ] && { - local fallback="" - config_get fallback "$network" prefix_fallback - - [ "$fallback" == "relay" ] && restart_relay "$network" fallback - [ "$fallback" == "masquerade" ] && setup_masquerading start "$network" "$device" - } -} - - -restart_master_relay() { - local network="$1" - local mode="$2" - - # Disable active relaying to this interface - config_get relay_master "$network" relay_master - [ -z "$relay_master" ] && return - network_is_up "$relay_master" || return - - # Detect running mode - local pid_fallback="/var/run/ipv6-relay-fallback-$relay_master.pid" - local pid_forced="/var/run/ipv6-relay-forced-$relay_master.pid" - [ -z "$mode" -a -f "$pid_fallback" ] && mode="fallback" - [ -z "$mode" -a -f "$pid_forced" ] && mode="forced" - - # Restart relay if running or start requested - [ -n "$mode" ] && restart_relay "$relay_master" "$mode" -} - - -set_site_border() { - local network="$1" - local device="$2" - - local fwscript="/var/etc/ipv6-firewall.d/site-border-$network.sh" - local chain="ipv6-site-border-$network" - - if [ -n "$device" ]; then - local site_border - config_get_bool site_border "$network" site_border 1 - [ "$site_border" == "1" ] || return - - mkdir -p $(dirname "$fwscript") - echo "ip6tables -N $chain" > "$fwscript" - echo "ip6tables -F $chain" >> "$fwscript" - echo "ip6tables -A $chain -o $device -j REJECT --reject-with icmp6-no-route" >> "$fwscript" - echo "ip6tables -A $chain -i $device -j REJECT --reject-with icmp6-no-route" >> "$fwscript" - echo "ip6tables -A ipv6-site-border -j $chain" >> "$fwscript" - . "$fwscript" - else - [ -f "$fwscript" ] || return - rm -f "$fwscript" - ip6tables -D ipv6-site-border -j "$chain" - ip6tables -F "$chain" - ip6tables -X "$chain" - fi -} - - -set_forward_border() { - local network="$1" - local device="$2" - local method="$3" - local fwscript="/var/etc/ipv6-firewall.d/forward-border-$network.sh" - - if [ "$method" == "enable" ]; then - mkdir -p $(dirname "$fwscript") - echo "ip6tables -A forwarding_rule -o \"$device\" -j REJECT --reject-with icmp6-no-route" > "$fwscript" - . "$fwscript" - else - [ -f "$fwscript" ] || return - rm -f "$fwscript" - # Racy race race - ip6tables -D forwarding_rule -o "$device" -j REJECT --reject-with icmp6-no-route 2>/dev/null - ip6tables -D forwarding_rule -o "$device" -j REJECT --reject-with icmp6-no-route 2>/dev/null - fi -} - - -disable_interface() { - local network="$1" - - # Delete all prefixes routed to this interface - ubus call 6distributed delprefix '{"network": "'"$network"'"}' - - # Restart Relay - restart_master_relay "$network" - - # Disable distribution - disable_router "$network" - - # Disable any active relays, masquerading rules and NPT rules - stop_relay "$network" - setup_masquerading stop "$network" - setup_npt_chain stop "$network" - - # Disable DHCPv6 client if enabled, state script will take care - stop_service /usr/sbin/odhcp6c "/var/run/ipv6-dhcpv6-$network.pid" - - # Stop site-border - set_site_border "$network" -} - - -enable_ula_prefix() { - local network="$1" - local ula="$2" - local device="$3" - [ -z "$ula" ] && ula="global" - - # ULA-integration - local ula_prefix="" - config_get ula_prefix "$ula" ula_prefix - - # ULA auto configuration (first init) - [ "$ula_prefix" == "auto" ] && { - local r1="" - local r2="" - local r3="" - - # Sometimes results are empty, therefore try until it works... - while [ -z "$r1" -o -z "$r2" -o -z "$r3" ]; do - r1=$(printf "%02x" $(($( $conf - echo "enable-ra" >> $conf - /etc/init.d/dnsmasq restart - else - local opts="" - [ "$always_default" == "1" ] && opts="-u" - - local pid="/var/run/ipv6-router-$network.pid" - start_service "/usr/sbin/6relayd -S $opts . $device" "$pid" - fi - - # Try relaying if necessary - restart_master_relay "$network" -} - - -enable_dhcpv6() { - local network="$1" - local device="$2" - - # Configure DHCPv6-client - local dhcp6_opts="$device" - - # Configure DHCPv6-client (e.g. requested prefix) - local request_prefix - config_get request_prefix "$network" request_prefix - [ -z "$request_prefix" ] && request_prefix="auto" - [ "$request_prefix" != "no" ] && { - [ "$request_prefix" == "auto" ] && request_prefix=0 - dhcp6_opts="-P$request_prefix $dhcp6_opts" - } - - # Start DHCPv6 client - local pid="/var/run/ipv6-dhcpv6-$network.pid" - start_service "/usr/sbin/odhcp6c -s/lib/ipv6/dhcpv6.sh $dhcp6_opts" "$pid" -} - - -enable_6to4() { - local network="$1" - local device="$2" - local mode="$3" - - local prefixlen="48" - [ "$mode" == "6rd" ] && { - local ip4prefix=$(uci_get network "$network" ip4prefixlen 0) - local ip6prefix=$(uci_get network "$network" ip6prefixlen 32) - prefixlen=$(($ip6prefix + 32 - $ip4prefix)) - } - - local prefix="" - network_get_ipaddr6 prefix "$network" - - announce_prefix "$prefix/$prefixlen" "$network" "$device" -} - - -enable_interface() -{ - local network="$1" - local device="$2" - local mode="" - - config_get mode "$network" mode - [ -n "$mode" -a "$mode" != "none" ] || return - - # Compatibility with old mode names - [ "$mode" == "downstream" ] && mode=router - [ "$mode" == "upstream" ] && mode=dhcpv6 - - # Enable site-border - [ "$mode" == "static" -o "$mode" == "dhcpv6" -o "$mode" == "6to4" -o "$mode" == "6in4" ] && set_site_border "$network" "$device" - - # Run mode startup code - enable_static "$network" "$device" - [ "$mode" == "dhcpv6" ] && enable_dhcpv6 "$network" "$device" - [ "$mode" == "router" ] && enable_router "$network" "$device" - [ "$mode" == "6to4" -o "$mode" == "6rd" ] && enable_6to4 "$network" "$device" "$mode" - [ "$mode" == "relay" ] && restart_master_relay "$network" forced -}