summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-07-28 12:47:47 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-07-28 12:47:47 -0700
commite0471ad3e2144d3f99437a624344f2760195d89c (patch)
tree3f4c2b0cc5f761056a9a5bc1a9a99b150df2bb4a
parent55c8a5e54d3a758b2aa64f52ec3a5549ad4d5c7c (diff)
downloadvyatta-cfg-quagga-e0471ad3e2144d3f99437a624344f2760195d89c.tar.gz
vyatta-cfg-quagga-e0471ad3e2144d3f99437a624344f2760195d89c.zip
Add new program to check prefix boundary
Using perl to check prefix boundary, is slow because of the overhead of compiling the same script many times. So convert this simple task to a C program.
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac3
-rw-r--r--src/check_prefix_boundary.c135
-rw-r--r--templates/protocols/bgp/node.tag/aggregate-address/node.def2
-rw-r--r--templates/protocols/bgp/node.tag/network/node.def3
-rw-r--r--templates/protocols/ospf/area/node.tag/network/node.def2
-rw-r--r--templates/protocols/ospf/area/node.tag/range/node.def2
-rw-r--r--templates/protocols/ospf/area/node.tag/range/node.tag/substitute/node.def2
-rw-r--r--templates/protocols/rip/network-distance/node.def2
-rw-r--r--templates/protocols/rip/network/node.def2
-rw-r--r--templates/protocols/rip/route/node.def2
-rw-r--r--templates/protocols/static/interface-route/node.def2
-rw-r--r--templates/protocols/static/interface-route6/node.def2
-rw-r--r--templates/protocols/static/route/node.def2
-rw-r--r--templates/protocols/static/route/node.tag/next-hop/node.def28
-rw-r--r--templates/protocols/static/route6/node.def2
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(@)"