diff options
author | bluhm <bluhm@openbsd.org> | 2010-08-22 20:55:10 +0000 |
---|---|---|
committer | bluhm <bluhm@openbsd.org> | 2010-08-22 20:55:10 +0000 |
commit | 89db4f922b54b65468cde15dc7e10f6fb44338fe (patch) | |
tree | f60da1ccfb9a6583fac76b0c613403924311f33b /usr.sbin/ospf6d/rde.c | |
parent | Origin network-LSA with options based on the options of the link-LSAs. (diff) | |
download | wireguard-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.c | 35 |
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)); |