diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/check_prefix_boundary.c | 135 | ||||
-rw-r--r-- | templates/protocols/bgp/node.tag/aggregate-address/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/bgp/node.tag/network/node.def | 3 | ||||
-rw-r--r-- | templates/protocols/ospf/area/node.tag/network/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/ospf/area/node.tag/range/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/ospf/area/node.tag/range/node.tag/substitute/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/rip/network-distance/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/rip/network/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/rip/route/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/static/interface-route/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/static/interface-route6/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/static/route/node.def | 2 | ||||
-rw-r--r-- | templates/protocols/static/route/node.tag/next-hop/node.def | 28 | ||||
-rw-r--r-- | templates/protocols/static/route6/node.def | 2 |
16 files changed, 169 insertions, 25 deletions
diff --git a/Makefile.am b/Makefile.am index 223cf196..6772ef77 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,6 +8,9 @@ sbin_SCRIPTS += scripts/policy/vyatta-check-as-prepend.pl sbin_SCRIPTS += scripts/vyatta-vtysh.pl sbin_SCRIPTS += scripts/vyatta-policy-action-verify.pl sbin_SCRIPTS += scripts/vyatta-gateway-static_route-check.pl +sbin_PROGRAMS = src/check_prefix_boundary + +src_check_prefix_boundary = src/check_prefix_boundary.c curver_DATA = cfg-version/quagga@1 diff --git a/configure.ac b/configure.ac index 6489ec9a..9485cf62 100644 --- a/configure.ac +++ b/configure.ac @@ -15,6 +15,9 @@ AC_CONFIG_AUX_DIR([config]) AM_INIT_AUTOMAKE([gnu no-dist-gzip dist-bzip2 subdir-objects]) AC_PREFIX_DEFAULT([/opt/vyatta]) +AC_PROG_CC +AM_PROG_CC_C_O + AC_ARG_ENABLE([nostrip], AC_HELP_STRING([--enable-nostrip], [include -nostrip option during packaging]), diff --git a/src/check_prefix_boundary.c b/src/check_prefix_boundary.c new file mode 100644 index 00000000..1c9ee30a --- /dev/null +++ b/src/check_prefix_boundary.c @@ -0,0 +1,135 @@ +/* + * Check format of network prefix + */ +#include <stdio.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> + +typedef struct +{ + uint8_t family; + uint8_t bytelen; + unsigned int plen; + uint32_t data[4]; +} inet_prefix; + +static void err(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + exit(1); +} + +static void usage(void) +{ + fprintf(stderr, "Usage: check-prefix-boundary [-4|-6] address/prefix\n"); + exit(1); +} + +static void get_addr_1(inet_prefix *addr, const char *name, int family) +{ + memset(addr, 0, sizeof(*addr)); + + if (strchr(name, ':')) { + addr->family = AF_INET6; + addr->bytelen = 16; + if (family != AF_UNSPEC && family != AF_INET6) + err("IPV6 address not allowed\n"); + + if (inet_pton(AF_INET6, name, addr->data) <= 0) + err("Invalid IPV6 address: %s\n", name); + + return; + } + + addr->family = AF_INET; + addr->bytelen = 4; + if (family != AF_UNSPEC && family != AF_INET) + err("IPV4 address not allowed\n"); + + if (inet_pton(AF_INET, name, addr->data) <= 0) + err("Invalid IPV4 address: %s\n", name); + return; +} + +static void get_prefix_1(inet_prefix *dst, char *arg, int family) +{ + char *slash, *endp; + + memset(dst, 0, sizeof(*dst)); + + slash = strchr(arg, '/'); + if (!slash || slash[1] == '\0') + err("Missing prefix length\n"); + *slash = 0; + + get_addr_1(dst, arg, family); + + dst->plen = strtoul(slash+1, &endp, 0); + if (*endp != '\0') + err("Invalid character in prefix length\n"); + + if (dst->plen > 8 * dst->bytelen) + err("Prefix length is too large\n"); + + *slash = '/'; +} + +static void get_netmask(inet_prefix *msk, const inet_prefix *dst) +{ + int i, plen = dst->plen; + + memset(msk, 0, sizeof(*msk)); + msk->family = dst->family; + msk->bytelen = dst->bytelen; + + for (i = 0; plen > 0 && i < dst->bytelen / sizeof(uint32_t); i++) { + uint32_t m = (plen > 32) ? ~0 : htonl(~0 << (32 - plen)); + + msk->data[i] = dst->data[i] & m; + plen -= 32; + } +} + +int main(int argc, char **argv) +{ + int family = AF_UNSPEC; + + while (--argc) { + char *arg = *++argv; + inet_prefix dst, msk; + + if (arg[0] == '-') + switch(arg[1]) { + case '4': + family = AF_INET; + break; + case '6': + family = AF_INET6; + break; + default: + usage(); + } + + get_prefix_1(&dst, arg, family); + get_netmask(&msk, &dst); + + if (memcmp(msk.data, dst.data, dst.bytelen) != 0) { + char buf[INET_ADDRSTRLEN]; + err("Prefix not on a natural network boundary." + "Did you mean %s?\n", + inet_ntop(msk.family, msk.data, buf, sizeof buf)); + } + } + + return 0; +} diff --git a/templates/protocols/bgp/node.tag/aggregate-address/node.def b/templates/protocols/bgp/node.tag/aggregate-address/node.def index 6e2ba210..4f2c63bc 100644 --- a/templates/protocols/bgp/node.tag/aggregate-address/node.def +++ b/templates/protocols/bgp/node.tag/aggregate-address/node.def @@ -2,7 +2,7 @@ tag: type: ipv4net help: Set a BGP aggregate network comp_help: \1 <x.x.x.x/x>\taggregate network -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" delete: touch /tmp/`echo $VAR(@) | sed 's!/!!'`.$PPID end: ${vyatta_sbindir}/vyatta-vtysh.pl -noerr \ -c "configure terminal" \ diff --git a/templates/protocols/bgp/node.tag/network/node.def b/templates/protocols/bgp/node.tag/network/node.def index ad39bbe3..43585bc5 100644 --- a/templates/protocols/bgp/node.tag/network/node.def +++ b/templates/protocols/bgp/node.tag/network/node.def @@ -2,8 +2,7 @@ tag: type: ipv4net help: Set a BGP network comp_help: \1 <x.x.x.x/x>\tnetwork -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)"; - "Prefix doesn't fall on a natural boundry" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" commit:expression: !($VAR(./backdoor/) != "" && $VAR(./route-map/) != ""); "protocols bgp $VAR(../@) network $VAR(@): May specify route-map or backdoor but not both" delete: touch /tmp/`echo $VAR(@) | sed 's!/!!'`.$PPID diff --git a/templates/protocols/ospf/area/node.tag/network/node.def b/templates/protocols/ospf/area/node.tag/network/node.def index d50adfc5..8a5173f4 100644 --- a/templates/protocols/ospf/area/node.tag/network/node.def +++ b/templates/protocols/ospf/area/node.tag/network/node.def @@ -2,7 +2,7 @@ multi: type: ipv4net help: Set OSPF network priority: 1 -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" create:expression: "${vyatta_sbindir}/vyatta-vtysh.pl -c \"configure terminal\" \ -c \"router ospf\" \ -c \"network $VAR(@) area $VAR(../@)\"; " diff --git a/templates/protocols/ospf/area/node.tag/range/node.def b/templates/protocols/ospf/area/node.tag/range/node.def index b8f514e2..8293a1e5 100644 --- a/templates/protocols/ospf/area/node.tag/range/node.def +++ b/templates/protocols/ospf/area/node.tag/range/node.def @@ -1,7 +1,7 @@ tag: type: ipv4net help: Set to summarize routes matching prefix (border routers only) -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" delete: touch /tmp/ospf-range.$PPID diff --git a/templates/protocols/ospf/area/node.tag/range/node.tag/substitute/node.def b/templates/protocols/ospf/area/node.tag/range/node.tag/substitute/node.def index 67ef935a..ceb6ff7f 100644 --- a/templates/protocols/ospf/area/node.tag/range/node.tag/substitute/node.def +++ b/templates/protocols/ospf/area/node.tag/range/node.tag/substitute/node.def @@ -1,3 +1,3 @@ type: ipv4net help: Set to announce area range as another prefix -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" diff --git a/templates/protocols/rip/network-distance/node.def b/templates/protocols/rip/network-distance/node.def index e0e64003..bb8a483e 100644 --- a/templates/protocols/rip/network-distance/node.def +++ b/templates/protocols/rip/network-distance/node.def @@ -1,7 +1,7 @@ tag: type: ipv4net help: Set source network -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" commit:expression: $VAR(./distance/) != ""; "Must specify distance for network $VAR(@)" delete:expression: "touch /tmp/rip-dist.$PPID" end:expression: "if [ -n \"$VAR(./access-list/@)\" ]; then \ diff --git a/templates/protocols/rip/network/node.def b/templates/protocols/rip/network/node.def index 07c36d73..4fd37c09 100644 --- a/templates/protocols/rip/network/node.def +++ b/templates/protocols/rip/network/node.def @@ -1,7 +1,7 @@ multi: type: ipv4net help: Set RIP network -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" create:expression: "${vyatta_sbindir}/vyatta-vtysh.pl -c \"configure terminal\" -c \"router rip\" \ -c \"network $VAR(@)\"; " delete:expression: "${vyatta_sbindir}/vyatta-vtysh.pl -c \"configure terminal\" -c \"router rip\" \ diff --git a/templates/protocols/rip/route/node.def b/templates/protocols/rip/route/node.def index 58b6c206..067b8fc1 100644 --- a/templates/protocols/rip/route/node.def +++ b/templates/protocols/rip/route/node.def @@ -1,7 +1,7 @@ multi: type: ipv4net help: Set RIP static route -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" create:expression: "${vyatta_sbindir}/vyatta-vtysh.pl -c \"configure terminal\" -c \"router rip\" \ -c \"route $VAR(@)\" " delete:expression: "${vyatta_sbindir}/vyatta-vtysh.pl -c \"configure terminal\" -c \"router rip\" \ diff --git a/templates/protocols/static/interface-route/node.def b/templates/protocols/static/interface-route/node.def index 0e732ea9..5317a93c 100644 --- a/templates/protocols/static/interface-route/node.def +++ b/templates/protocols/static/interface-route/node.def @@ -1,4 +1,4 @@ tag: type: ipv4net help: Set an interface-based static route -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" diff --git a/templates/protocols/static/interface-route6/node.def b/templates/protocols/static/interface-route6/node.def index 04624589..1f2f561a 100644 --- a/templates/protocols/static/interface-route6/node.def +++ b/templates/protocols/static/interface-route6/node.def @@ -1,4 +1,4 @@ tag: type: ipv6net help: Set an interface-based IPv6 static route -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" diff --git a/templates/protocols/static/route/node.def b/templates/protocols/static/route/node.def index 78ead81d..9f5eb0db 100644 --- a/templates/protocols/static/route/node.def +++ b/templates/protocols/static/route/node.def @@ -1,4 +1,4 @@ tag: type: ipv4net help: Set a static route -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" diff --git a/templates/protocols/static/route/node.tag/next-hop/node.def b/templates/protocols/static/route/node.tag/next-hop/node.def index 1bb4b579..f93b1270 100644 --- a/templates/protocols/static/route/node.tag/next-hop/node.def +++ b/templates/protocols/static/route/node.tag/next-hop/node.def @@ -1,15 +1,19 @@ tag: type: ipv4 help: Set the next-hop router -delete:expression: "touch /tmp/static.$PPID" -end:expression: "if [ -f \"/tmp/static.$PPID\" ]; then \ - if ${vyatta_sbindir}/vyatta-gateway-static_route-check.pl \"$VAR(../@)\" \"$VAR(@)\"; then \ - ${vyatta_sbindir}/vyatta-vtysh.pl -c \"configure terminal\" -c \"no ip route $VAR(../@) $VAR(@)\" ; \ - fi; - rm /tmp/static.$PPID; \ - else \ - if [ -n \"$VAR(./distance/@)\" ]; then \ - DIST=\"$VAR(./distance/@)\"; \ - fi; \ - ${vyatta_sbindir}/vyatta-vtysh.pl -c \"configure terminal\" -c \"ip route $VAR(../@) $VAR(@) $DIST \" ; \ - fi; " +delete: touch /tmp/static.$PPID +end: if [[ -f /tmp/static.$PPID ]] + then + if ${vyatta_sbindir}/vyatta-gateway-static_route-check.pl \ + "$VAR(../@)" "$VAR(@)" + then + vyatta-vtysh -c "configure terminal" -c "no ip route $VAR(../@) $VAR(@)" + fi + rm -f /tmp/static.$PPID + else + if [[ -n "$VAR(./distance/@)" ]] + then + DIST="$VAR(./distance/@)" + fi + vyatta-vtysh -c "configure terminal" -c "ip route $VAR(../@) $VAR(@) $DIST" ; \ + fi diff --git a/templates/protocols/static/route6/node.def b/templates/protocols/static/route6/node.def index 7f95d0be..86ca5826 100644 --- a/templates/protocols/static/route6/node.def +++ b/templates/protocols/static/route6/node.def @@ -1,4 +1,4 @@ tag: type: ipv6net help: Set a static IPv6 route -syntax:expression: exec "/opt/vyatta/sbin/vyatta_quagga_utils.pl --check-prefix-boundry $VAR(@)" +syntax:expression: exec "${sbin_dir}/check_prefix_boundary $VAR(@)" |