Permalink
Browse files

implemented a static MRIB for RPF calculation.

  • Loading branch information...
1 parent 8ac15ab commit db63f788ba608954081990bf8b17b1e8b14edd77 suz committed Jul 14, 2005
View
@@ -1,7 +1,12 @@
CHANGELOG for KAME kit
-$KAME: CHANGELOG,v 1.2780 2005/07/13 11:32:29 keiichi Exp $
+$KAME: CHANGELOG,v 1.2781 2005/07/14 12:39:03 suz Exp $
<200507>
+2005-07-14 SUZUKI, Shinsuke <suz@kame.net>
+ * kame/kame/pim6sd/{cfparse.y, cftoken.l, pim6sd.conf.5,
+ routesock.c, routesock.h}: implemented a static MRIB
+ for RPF calculation.
+
Wed Jul 13 20:26:31 JST 2005 keiichi@iijlab.net
* kame/kame/ndp/ndp.c
fixed the proxy directive to work properly.
View
@@ -1,4 +1,4 @@
-/* $KAME: cfparse.y,v 1.37 2005/05/19 08:11:26 suz Exp $ */
+/* $KAME: cfparse.y,v 1.38 2005/07/14 12:39:03 suz Exp $ */
/*
* Copyright (C) 1999 WIDE Project.
@@ -38,6 +38,7 @@
#include <netinet/icmp6.h>
#include <netinet6/ip6_mroute.h>
#include <arpa/inet.h>
+#include <netdb.h>
#include <string.h>
#include <syslog.h>
#include <stdio.h>
@@ -46,6 +47,7 @@
#include "defs.h"
#include "vif.h"
#include "mrt.h"
+#include "routesock.h"
#include "rp.h"
#include "var.h"
@@ -82,19 +84,20 @@ struct attr_list {
double number;
struct in6_prefix prefix;
struct staticrp staticrp;
+ struct staticrt staticrt;
}attru;
};
enum {IFA_FLAG, IFA_PREFERENCE, IFA_METRIC, RPA_PRIORITY, RPA_TIME,
BSRA_PRIORITY, BSRA_TIME, BSRA_MASKLEN, IN6_PREFIX, THRESA_RATE,
THRESA_INTERVAL,
IFA_ROBUST, IFA_QUERY_INT, IFA_QUERY_INT_RESP, IFA_MLD_VERSION, IFA_LLQI,
- RPA_STATICADDR,
+ RPA_STATICADDR, STATICRT,
};
static int strict; /* flag if the grammer check is strict */
static struct attr_list *rp_attr, *bsr_attr, *grp_prefix, *regthres_attr,
- *datathres_attr, *static_rp;
+ *datathres_attr, *static_rp, *static_rt;
static int srcmetric, srcpref, helloperiod, jpperiod, granularity,
datatimo, regsuptimo, probetime, asserttimo;
static double helloperiod_coef, jpperiod_coef;
@@ -113,6 +116,7 @@ static int phyint_config __P((void));
static int rp_config __P((void));
static int bsr_config __P((void));
static int static_rp_config __P((void));
+static int static_rt_config __P((void));
static int regthres_config __P((void));
static int datathres_config __P((void));
@@ -133,6 +137,7 @@ static int datathres_config __P((void));
%token ROBUST QUERY_INT QUERY_INT_RESP MLD_VERSION LLQI
%token GRPPFX
%token STATICRP
+%token STATIC
%token CANDRP CANDBSR TIME PRIORITY MASKLEN
%token NUMBER STRING SLASH ANY
%token REGTHRES DATATHRES RATE INTERVAL
@@ -159,6 +164,7 @@ statement:
| candrp_statement
| candbsr_statement
| staticrp_statement
+ | staticroute_statement
| grppfx_statement
| regthres_statement
| datathres_statement
@@ -448,7 +454,6 @@ staticrp_statement:
new->attru.staticrp = entry;
new->next = static_rp;
static_rp = new;
- static_rp_flag = TRUE;
}
;
@@ -458,6 +463,77 @@ staticrp_priority :
{ $$ = $2; }
;
+staticroute_statement:
+ STATIC STRING SLASH NUMBER STRING EOS {
+ struct staticrt entry;
+ struct attr_list *new;
+ struct addrinfo hints, *res;
+ int syntax_ng = 0;
+
+ bzero(&entry, sizeof(entry));
+ entry.paddr.sin6_family = AF_INET6;
+ entry.paddr.sin6_len = sizeof(entry.paddr);
+ if (inet_pton(AF_INET6, $2.v, &entry.paddr.sin6_addr) != 1) {
+ yywarn("invalid IPv6 address: %s", $2.v);
+ syntax_ng = 1;
+ }
+ if (IN6_IS_ADDR_MULTICAST(&entry.paddr.sin6_addr)) {
+ yywarn("static route prefix(%s) must be unicast",
+ sa6_fmt(&entry.paddr));
+ syntax_ng = 1;
+ }
+ if (IN6_IS_ADDR_LINKLOCAL(&entry.paddr.sin6_addr)) {
+ yywarn("static route prefix (%s) has a narrow scope ",
+ sa6_fmt(&entry.paddr));
+ syntax_ng = 1;
+ }
+ free($2.v); /* XXX: which was allocated dynamically */
+
+ entry.plen = $4;
+ if (entry.plen > 128) {
+ yywarn("invalid prefix length: %d", entry.plen);
+ syntax_ng = 1;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo($5.v, NULL, &hints, &res)) {
+ yywarn("invalid gateway address: %s", $5.v);
+ syntax_ng = 1;
+ }
+ if (res == NULL || res->ai_addrlen == 0) {
+ yywarn("invalid gateway address: %s", $5.v);
+ syntax_ng = 1;
+ }
+ if (res && res->ai_addr) {
+ struct sockaddr_in6 *addr;
+ addr = (struct sockaddr_in6 *)res->ai_addr;
+ if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
+ yywarn("gateway address (%s) must be a "
+ "link-local address", sa6_fmt(addr));
+ syntax_ng = 1;
+ }
+ }
+ free($5.v); /* XXX: which was allocated dynamically */
+
+ if (syntax_ng)
+ break;
+ memcpy(&entry.gwaddr, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+
+ if ((new = malloc(sizeof(*new))) == NULL) {
+ yyerror("malloc failed");
+ return(0);
+ }
+ memset(new, 0, sizeof(*new));
+ new->type = STATICRT;
+ new->attru.staticrt = entry;
+ new->next = static_rt;
+ static_rt = new;
+ }
+ ;
+
/* group_prefix <group-addr>/<prefix_len> */
grppfx_statement:
GRPPFX STRING SLASH NUMBER EOS {
@@ -964,6 +1040,27 @@ static_rp_config()
}
static int
+static_rt_config()
+{
+ struct attr_list *al;
+
+ for (al = static_rt; al; al = al->next) {
+ struct staticrt *entry;
+ int error;
+
+ if (al->type != STATICRT)
+ continue;
+ entry = &al->attru.staticrt;
+
+ error = add_static_rt_entry(&entry->paddr, entry->plen,
+ &entry->gwaddr);
+ if (error)
+ return error;
+ }
+ return(0);
+}
+
+static int
rp_config()
{
struct attr_list *al;
@@ -1199,6 +1296,8 @@ cf_post_config()
static_rp_config();
+ static_rt_config();
+
if (cand_bsr_flag == TRUE)
bsr_config();
@@ -1226,6 +1325,7 @@ cf_post_config()
if (rp_attr) free_attr_list(rp_attr);
if (bsr_attr) free_attr_list(bsr_attr);
if (static_rp) free_attr_list(static_rp);
+ if (static_rt) free_attr_list(static_rt);
if (regthres_attr) free_attr_list(regthres_attr);
if (datathres_attr) free_attr_list(datathres_attr);
for (vifi = 0, v = uvifs; vifi < numvifs ; ++vifi , ++v)
@@ -1245,7 +1345,7 @@ cf_init(s, d)
debugonly = d;
rp_attr = bsr_attr = grp_prefix = regthres_attr = datathres_attr
- = static_rp = NULL;
+ = static_rp = static_rt = NULL;
cand_rp_flag = cand_bsr_flag = static_rp_flag = FALSE;
cand_rp_ifname = cand_bsr_ifname = NULL;
@@ -1,4 +1,4 @@
-/* $KAME: cftoken.l,v 1.19 2003/04/30 05:09:01 suz Exp $ */
+/* $KAME: cftoken.l,v 1.20 2005/07/14 12:39:04 suz Exp $ */
%{
/*
@@ -91,6 +91,7 @@ slash \/
%s S_PHYINT S_IFCONF S_CANDRP S_CANDBSR S_PREFIX
%s S_THRES
%s S_STATICRP
+%s S_STATIC
%%
%{
@@ -590,6 +591,10 @@ slash \/
<S_STATICRP>priority { YYD_ECHO; return(PRIORITY); }
<S_STATICRP>{semi} { DP("end static_rp"); BEGIN S_CNF; return(EOS); }
+ /* static route */
+<S_CNF>static { YYD_ECHO; BEGIN S_STATIC; return(STATIC); }
+<S_STATIC>{semi} { DP("end static"); BEGIN S_CNF; return(EOS); }
+
/* various parameters */
<S_CNF>default_source_metric { YYD_ECHO; return(SRCMETRIC); }
<S_CNF>default_source_preference { YYD_ECHO; return(SRCPREF); }
@@ -1,4 +1,4 @@
-.\" $KAME: pim6sd.conf.5,v 1.23 2004/11/04 11:16:22 suz Exp $
+.\" $KAME: pim6sd.conf.5,v 1.24 2005/07/14 12:39:04 suz Exp $
.\"
.\" Copyright (C) 1999 WIDE Project.
.\" All rights reserved.
@@ -289,6 +289,13 @@ specifies the priority of the RP.
The default value is 0, which means the highest priority.
.\"
.It Xo
+.Ic static
+.Ar prefix
+.Ar address
+.Ic ;
+.Xc
+Specifics a static route only for RPF calculation.
+.It Xo
.Ic static_rp
.Ar prefix
.Ar address
@@ -1,4 +1,4 @@
-/* $KAME: routesock.c,v 1.21 2003/10/21 08:15:45 itojun Exp $ */
+/* $KAME: routesock.c,v 1.22 2005/07/14 12:39:04 suz Exp $ */
/*
* Copyright (c) 1998-2001
@@ -57,6 +57,7 @@
#include <sys/param.h>
#include <sys/file.h>
+#include <sys/queue.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/socket.h>
@@ -81,6 +82,7 @@
#include "routesock.h"
#include "mrt.h"
#include "inet6.h"
+#include "pimd.h"
#ifdef HAVE_ROUTING_SOCKETS
union sockunion
@@ -175,6 +177,7 @@ k_req_incoming(source, rpfp)
register char *cp = m_rtmsg.m_space;
register int l;
struct rpfctl rpfinfo;
+ struct staticrt *entry;
/* TODO: a hack!!!! */
#ifdef HAVE_SA_LEN
@@ -205,6 +208,26 @@ k_req_incoming(source, rpfp)
return (TRUE);
}
+ /*
+ * check the static-rpf configuration
+ */
+ if ((entry = find_static_rt_entry(source)) != NULL) {
+ mifi_t mifi;
+ struct pim_nbr_entry *nbr;
+
+ if ((mifi = find_vif_direct_local(&entry->gwaddr)) != NO_VIF) {
+ for (nbr= uvifs[mifi].uv_pim_neighbors; nbr; nbr = nbr->next) {
+ if (inet6_equal(&nbr->address, &entry->gwaddr))
+ break;
+ }
+ if (nbr != NULL) {
+ rpfp->rpfneighbor = nbr->address;
+ rpfp->iif = mifi;
+ return (TRUE);
+ }
+ }
+ }
+
/* prepare the routing socket params */
rtm_addrs |= RTA_DST;
rtm_addrs |= RTA_IFP;
@@ -449,3 +472,53 @@ k_req_incoming(source, rpfcinfo)
}
#endif /* HAVE_ROUTING_SOCKETS */
+
+TAILQ_HEAD(staticrt_list, staticrt);
+static struct staticrt_list staticrt_head;
+
+int add_static_rt_entry(paddr, plen, gwaddr)
+ struct sockaddr_in6 *paddr;
+ int plen;
+ struct sockaddr_in6 *gwaddr;
+{
+ struct staticrt *entry;
+ struct in6_addr mask;
+
+ memset(&mask, 0, sizeof(mask));
+ MASKLEN_TO_MASK6(plen, mask);
+
+ if (TAILQ_EMPTY(&staticrt_head))
+ TAILQ_INIT(&staticrt_head);
+
+ TAILQ_FOREACH(entry, &staticrt_head, link) {
+ if (inet6_same_prefix(paddr, &entry->paddr, &mask))
+ return -1;
+ }
+ entry = malloc(sizeof(struct staticrt));
+ entry->paddr = *paddr;
+ entry->plen = plen;
+ entry->gwaddr = *gwaddr;
+ TAILQ_INSERT_TAIL(&staticrt_head, entry, link);
+
+ return 0;
+}
+
+struct staticrt *find_static_rt_entry(addr)
+ struct sockaddr_in6 *addr;
+{
+ struct staticrt *entry;
+
+ if (TAILQ_EMPTY(&staticrt_head))
+ return NULL;
+
+ TAILQ_FOREACH(entry, &staticrt_head, link) {
+ struct in6_addr mask;
+ memset(&mask, 0, sizeof(mask));
+ MASKLEN_TO_MASK6(entry->plen, mask);
+
+ if (inet6_match_prefix(addr, &entry->paddr, &mask))
+ return entry;
+ }
+ return NULL;
+}
+
Oops, something went wrong.

0 comments on commit db63f78

Please sign in to comment.