summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ospf6d/rde.c
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2010-08-22 20:55:10 +0000
committerbluhm <bluhm@openbsd.org>2010-08-22 20:55:10 +0000
commit89db4f922b54b65468cde15dc7e10f6fb44338fe (patch)
treef60da1ccfb9a6583fac76b0c613403924311f33b /usr.sbin/ospf6d/rde.c
parentOrigin network-LSA with options based on the options of the link-LSAs. (diff)
downloadwireguard-openbsd-89db4f922b54b65468cde15dc7e10f6fb44338fe.tar.xz
wireguard-openbsd-89db4f922b54b65468cde15dc7e10f6fb44338fe.zip
When removing an announced prefix, inherit the metric and ext_tag
from the LSA that is currently in the tree. Based on claudio@'s diff and his fix for ospfd. Additionally originate an LSA with external route tag correctly by writing the AS-external-LSA's bit T into the correct field. ok claudio@
Diffstat (limited to 'usr.sbin/ospf6d/rde.c')
-rw-r--r--usr.sbin/ospf6d/rde.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/usr.sbin/ospf6d/rde.c b/usr.sbin/ospf6d/rde.c
index 2a2e11e4844..b6e7da4cd81 100644
--- a/usr.sbin/ospf6d/rde.c
+++ b/usr.sbin/ospf6d/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.49 2010/07/09 12:39:46 bluhm Exp $ */
+/* $OpenBSD: rde.c,v 1.50 2010/08/22 20:55:10 bluhm Exp $ */
/*
* Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
@@ -1574,7 +1574,7 @@ orig_asext_lsa(struct rroute *rr, u_int16_t age)
{
struct lsa *lsa;
u_int32_t ext_tag;
- u_int16_t len, ext_off = 0;
+ u_int16_t len, ext_off;
len = sizeof(struct lsa_hdr) + sizeof(struct lsa_asext) +
LSA_PREFIXSIZE(rr->kr.prefixlen);
@@ -1586,8 +1586,8 @@ orig_asext_lsa(struct rroute *rr, u_int16_t age)
* XXX for now we don't do this.
*/
+ ext_off = len;
if (rr->kr.ext_tag) {
- ext_off = len;
len += sizeof(ext_tag);
}
if ((lsa = calloc(1, len)) == NULL)
@@ -1603,19 +1603,40 @@ orig_asext_lsa(struct rroute *rr, u_int16_t age)
lsa->hdr.seq_num = htonl(INIT_SEQ_NUM);
lsa->hdr.len = htons(len);
- lsa->data.asext.metric = htonl(rr->metric);
lsa->data.asext.prefix.prefixlen = rr->kr.prefixlen;
memcpy((char *)lsa + sizeof(struct lsa_hdr) + sizeof(struct lsa_asext),
&rr->kr.prefix, LSA_PREFIXSIZE(rr->kr.prefixlen));
+ lsa->hdr.ls_id = lsa_find_lsid(&asext_tree, lsa->hdr.type,
+ lsa->hdr.adv_rtr, comp_asext, lsa);
+
+ if (age == MAX_AGE) {
+ /* inherit metric and ext_tag from the current LSA,
+ * some routers don't like to get withdraws that are
+ * different from what they have in their table.
+ */
+ struct vertex *v;
+ v = lsa_find(NULL, lsa->hdr.type, lsa->hdr.ls_id,
+ lsa->hdr.adv_rtr);
+ if (v != NULL) {
+ rr->metric = ntohl(v->lsa->data.asext.metric);
+ if (rr->metric & LSA_ASEXT_T_FLAG) {
+ memcpy(&ext_tag, (char *)v->lsa + ext_off,
+ sizeof(ext_tag));
+ rr->kr.ext_tag = ntohl(ext_tag);
+ }
+ rr->metric &= LSA_METRIC_MASK;
+ }
+ }
+
if (rr->kr.ext_tag) {
- lsa->data.asext.prefix.options |= LSA_ASEXT_T_FLAG;
+ lsa->data.asext.metric = htonl(rr->metric | LSA_ASEXT_T_FLAG);
ext_tag = htonl(rr->kr.ext_tag);
memcpy((char *)lsa + ext_off, &ext_tag, sizeof(ext_tag));
+ } else {
+ lsa->data.asext.metric = htonl(rr->metric);
}
- lsa->hdr.ls_id = lsa_find_lsid(&asext_tree, lsa->hdr.type,
- lsa->hdr.adv_rtr, comp_asext, lsa);
lsa->hdr.ls_chksum = 0;
lsa->hdr.ls_chksum =
htons(iso_cksum(lsa, len, LS_CKSUM_OFFSET));