diff options
-rw-r--r-- | conf/cf-lex.l | 2 | ||||
-rw-r--r-- | lib/net.c | 34 | ||||
-rw-r--r-- | lib/net.h | 44 | ||||
-rw-r--r-- | nest/rt-table.c | 18 | ||||
-rw-r--r-- | proto/rpki/rpki.c | 2 | ||||
-rw-r--r-- | proto/static/config.Y | 6 |
6 files changed, 71 insertions, 35 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l index db847d37..a0e3c275 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -124,7 +124,7 @@ include ^{WHITE}*include{WHITE}*\".*\"{WHITE}*; } {DIGIT}+:{DIGIT}+ { - unsigned long int l, len1, len2; + unsigned long int l, len1 UNUSED, len2; char *e; errno = 0; @@ -177,33 +177,29 @@ net_hash(const net_addr *n) case NET_ROA6: return NET_HASH(n, roa6); case NET_FLOW4: return NET_HASH(n, flow4); case NET_FLOW6: return NET_HASH(n, flow6); + case NET_MPLS: return NET_HASH(n, mpls); default: bug("invalid type"); } } +#define NET_VALIDATE(a,t) net_validate_##t((const net_addr_##t *) a) + int -net_validate(const net_addr *N) +net_validate(const net_addr *n) { - switch (N->type) + switch (n->type) { - case NET_IP4: - case NET_VPN4: - case NET_ROA4: - case NET_FLOW4: - return net_validate_ip4((net_addr_ip4 *) N); - - case NET_IP6: - case NET_VPN6: - case NET_ROA6: - case NET_FLOW6: - return net_validate_ip6((net_addr_ip6 *) N); - - case NET_MPLS: - return net_validate_mpls((net_addr_mpls *) N); - - default: - return 0; + case NET_IP4: return NET_VALIDATE(n, ip4); + case NET_IP6: return NET_VALIDATE(n, ip6); + case NET_VPN4: return NET_VALIDATE(n, vpn4); + case NET_VPN6: return NET_VALIDATE(n, vpn6); + case NET_ROA4: return NET_VALIDATE(n, roa4); + case NET_ROA6: return NET_VALIDATE(n, roa6); + case NET_FLOW4: return NET_VALIDATE(n, flow4); + case NET_FLOW6: return NET_VALIDATE(n, flow6); + case NET_MPLS: return NET_VALIDATE(n, mpls); + default: return 0; } } @@ -37,6 +37,7 @@ #define NB_IP (NB_IP4 | NB_IP6) #define NB_VPN (NB_VPN4 | NB_VPN6) #define NB_FLOW (NB_FLOW4 | NB_FLOW6) +#define NB_DEST (NB_IP | NB_VPN | NB_MPLS) #define NB_ANY 0xffffffff @@ -457,23 +458,52 @@ static inline u32 net_hash_mpls(const net_addr_mpls *n) u32 net_hash(const net_addr *a); -static inline int net_validate_ip4(const net_addr_ip4 *n) +static inline int net_validate_px4(const ip4_addr prefix, uint pxlen) +{ + return (pxlen <= IP4_MAX_PREFIX_LENGTH) && + ip4_zero(ip4_and(prefix, ip4_not(ip4_mkmask(pxlen)))); +} + +static inline int net_validate_px6(const ip6_addr prefix, uint pxlen) { - return (n->pxlen <= IP4_MAX_PREFIX_LENGTH) && - ip4_zero(ip4_and(n->prefix, ip4_not(ip4_mkmask(n->pxlen)))); + return (pxlen <= IP6_MAX_PREFIX_LENGTH) && + ip6_zero(ip6_and(prefix, ip6_not(ip6_mkmask(pxlen)))); } +static inline int net_validate_ip4(const net_addr_ip4 *n) +{ return net_validate_px4(n->prefix, n->pxlen); } + static inline int net_validate_ip6(const net_addr_ip6 *n) +{ return net_validate_px6(n->prefix, n->pxlen); } + +static inline int net_validate_vpn4(const net_addr_vpn4 *n) +{ return net_validate_px4(n->prefix, n->pxlen); } + +static inline int net_validate_vpn6(const net_addr_vpn6 *n) +{ return net_validate_px6(n->prefix, n->pxlen); } + +static inline int net_validate_roa4(const net_addr_roa4 *n) { - return (n->pxlen <= IP6_MAX_PREFIX_LENGTH) && - ip6_zero(ip6_and(n->prefix, ip6_not(ip6_mkmask(n->pxlen)))); + return net_validate_px4(n->prefix, n->pxlen) && + (n->pxlen <= n->max_pxlen) && (n->max_pxlen <= IP4_MAX_PREFIX_LENGTH); } -static inline int net_validate_mpls(const net_addr_mpls *n) +static inline int net_validate_roa6(const net_addr_roa6 *n) { - return n->label < (1 << 20); + return net_validate_px6(n->prefix, n->pxlen) && + (n->pxlen <= n->max_pxlen) && (n->max_pxlen <= IP6_MAX_PREFIX_LENGTH); } +// FIXME: Better check, call flow_validate? +static inline int net_validate_flow4(const net_addr_flow4 *n) +{ return net_validate_px4(n->prefix, n->pxlen); } + +static inline int net_validate_flow6(const net_addr_flow6 *n) +{ return net_validate_px6(n->prefix, n->pxlen); } + +static inline int net_validate_mpls(const net_addr_mpls *n) +{ return n->label < (1 << 20); } + int net_validate(const net_addr *N); diff --git a/nest/rt-table.c b/nest/rt-table.c index 41f0f649..be764313 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -900,7 +900,6 @@ rte_validate(rte *e) int c; net *n = e->net; - // (n->n.pxlen > BITS_PER_IP_ADDRESS) || !ip_is_prefix(n->n.prefix,n->n.pxlen)) if (!net_validate(n->n.addr)) { log(L_WARN "Ignoring bogus prefix %N received via %s", @@ -916,12 +915,19 @@ rte_validate(rte *e) return 0; } + if (net_type_match(n->n.addr, NB_DEST) == !e->attrs->dest) + { + log(L_WARN "Ignoring route %N with invalid dest %d received via %s", + n->n.addr, e->attrs->dest, e->sender->proto->name); + return 0; + } + if ((e->attrs->dest == RTD_UNICAST) && !nexthop_is_sorted(&(e->attrs->nh))) - { - log(L_WARN "Ignoring unsorted multipath route %N received via %s", - n->n.addr, e->sender->proto->name); - return 0; - } + { + log(L_WARN "Ignoring unsorted multipath route %N received via %s", + n->n.addr, e->sender->proto->name); + return 0; + } return 1; } diff --git a/proto/rpki/rpki.c b/proto/rpki/rpki.c index 5459d9c3..349d2f70 100644 --- a/proto/rpki/rpki.c +++ b/proto/rpki/rpki.c @@ -903,7 +903,7 @@ rpki_postconfig(struct proto_config *CF) } static void -rpki_copy_config(struct proto_config *dest, struct proto_config *src) +rpki_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUSED) { /* FIXME: Should copy transport */ } diff --git a/proto/static/config.Y b/proto/static/config.Y index 6643ba69..66ae3c98 100644 --- a/proto/static/config.Y +++ b/proto/static/config.Y @@ -36,7 +36,10 @@ static_nexthop_new(void) static void static_route_finish(void) -{ } +{ + if (net_type_match(this_srt->net, NB_DEST) == !this_srt->dest) + cf_error("Unexpected or missing nexthop/type"); +} CF_DECLS @@ -119,6 +122,7 @@ stat_route: this_srt->via = $3; this_srt->mls = $5; } + | stat_route0 { this_srt->dest = RTD_NONE; } | stat_route0 DROP { this_srt->dest = RTD_BLACKHOLE; } | stat_route0 REJECT { this_srt->dest = RTD_UNREACHABLE; } | stat_route0 BLACKHOLE { this_srt->dest = RTD_BLACKHOLE; } |