summaryrefslogtreecommitdiff
path: root/proto/static
diff options
context:
space:
mode:
Diffstat (limited to 'proto/static')
-rw-r--r--proto/static/config.Y2
-rw-r--r--proto/static/static.c53
2 files changed, 54 insertions, 1 deletions
diff --git a/proto/static/config.Y b/proto/static/config.Y
index 77d2419f..621fdf9b 100644
--- a/proto/static/config.Y
+++ b/proto/static/config.Y
@@ -26,7 +26,7 @@ CF_GRAMMAR
CF_ADDTO(proto, static_proto '}')
static_proto_start: proto_start STATIC {
- this_proto = proto_config_new(&proto_static, sizeof(struct static_config));
+ this_proto = proto_config_new(&proto_static, sizeof(struct static_config), $1);
static_init_config((struct static_config *) this_proto);
}
;
diff --git a/proto/static/static.c b/proto/static/static.c
index 2f33d817..e5b293c0 100644
--- a/proto/static/static.c
+++ b/proto/static/static.c
@@ -470,6 +470,58 @@ static_reconfigure(struct proto *p, struct proto_config *new)
return 1;
}
+static void
+static_copy_routes(list *dlst, list *slst)
+{
+ struct static_route *dr, *sr;
+
+ init_list(dlst);
+ WALK_LIST(sr, *slst)
+ {
+ /* copy one route */
+ dr = cfg_alloc(sizeof(struct static_route));
+ memcpy(dr, sr, sizeof(struct static_route));
+
+ /* This fn is supposed to be called on fresh src routes, which have 'live'
+ fields (like .chain, .neigh or .installed) zero, so no need to zero them */
+
+ /* We need to copy multipath chain, because there are backptrs in 'if_name' */
+ if (dr->dest == RTD_MULTIPATH)
+ {
+ struct static_route *md, *ms, **mp_last;
+
+ mp_last = &(dr->mp_next);
+ for (ms = sr->mp_next; ms; ms = ms->mp_next)
+ {
+ md = cfg_alloc(sizeof(struct static_route));
+ memcpy(md, ms, sizeof(struct static_route));
+ md->if_name = (void *) dr; /* really */
+
+ *mp_last = md;
+ mp_last = &(md->mp_next);
+ }
+ *mp_last = NULL;
+ }
+
+ add_tail(dlst, (node *) dr);
+ }
+}
+
+static void
+static_copy_config(struct proto_config *dest, struct proto_config *src)
+{
+ struct static_config *d = (struct static_config *) dest;
+ struct static_config *s = (struct static_config *) src;
+
+ /* Shallow copy of everything */
+ proto_copy_rest(dest, src, sizeof(struct static_config));
+
+ /* Copy route lists */
+ static_copy_routes(&d->iface_routes, &s->iface_routes);
+ static_copy_routes(&d->other_routes, &s->other_routes);
+}
+
+
struct protocol proto_static = {
name: "Static",
template: "static%d",
@@ -479,6 +531,7 @@ struct protocol proto_static = {
shutdown: static_shutdown,
cleanup: static_cleanup,
reconfigure: static_reconfigure,
+ copy_config: static_copy_config
};
static void