From: Ondrej Zajicek Date: Sat, 12 Jan 2013 23:17:49 +0000 (+0100) Subject: Merge commit 'dd4da6f640fb581cbd7d1ca537bf382558492b8e' into integrated X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=07a6d8d1a03af190413f441a373944b1ad44cd82;p=thirdparty%2Fbird.git Merge commit 'dd4da6f640fb581cbd7d1ca537bf382558492b8e' into integrated --- 07a6d8d1a03af190413f441a373944b1ad44cd82 diff --cc proto/ospf/hello.c index 08ad6f919,6ec5c511b..c25187087 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@@ -258,55 -242,51 +258,55 @@@ ospf_hello_send(struct ospf_iface *ifa DBG("%s: Hello/Poll timer fired on interface %s with IP %I\n", p->name, ifa->iface->name, ifa->addr->ip); - /* Now we should send a hello packet */ pkt = ospf_tx_buffer(ifa); - op = &pkt->ospf_packet; - - /* Now fill ospf_hello header */ ospf_pkt_fill_hdr(ifa, pkt, HELLO_P); -#ifdef OSPFv2 - pkt->netmask = ipa_mkmask(ifa->addr->pxlen); - ipa_hton(pkt->netmask); - if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP)) - pkt->netmask = IPA_NONE; -#endif - - pkt->helloint = ntohs(ifa->helloint); - pkt->priority = ifa->priority; - -#ifdef OSPFv3 - pkt->iface_id = htonl(ifa->iface_id); - - pkt->options3 = ifa->oa->options >> 16; - pkt->options2 = ifa->oa->options >> 8; -#endif - pkt->options = ifa->oa->options; - -#ifdef OSPFv2 - pkt->deadint = htonl(ifa->deadint); - pkt->dr = htonl(ipa_to_u32(ifa->drip)); - pkt->bdr = htonl(ipa_to_u32(ifa->bdrip)); -#else /* OSPFv3 */ - pkt->deadint = htons(ifa->deadint); - pkt->dr = htonl(ifa->drid); - pkt->bdr = htonl(ifa->bdrid); -#endif + if (ospf_is_v2(po)) + { + struct ospf_hello2_packet *ps = (void *) pkt; + + ps->netmask = htonl(u32_mkmask(ifa->addr->pxlen)); + + if ((ifa->type == OSPF_IT_VLINK) || (ifa->type == OSPF_IT_PTP)) + ps->netmask = 0; + + ps->helloint = ntohs(ifa->helloint); + ps->options = ifa->oa->options; + ps->priority = ifa->priority; + ps->deadint = htonl(ifa->deadint); + ps->dr = htonl(ipa_to_u32(ifa->drip)); + ps->bdr = htonl(ipa_to_u32(ifa->bdrip)); + + length = sizeof(struct ospf_hello2_packet); + neighbors = ps->neighbors; + } + else + { + struct ospf_hello3_packet *ps = (void *) pkt; + - ps->iface_id = htonl(ifa->iface->index); ++ ps->iface_id = htonl(ifa->iface_id); + ps->priority = ifa->priority; + ps->options3 = ifa->oa->options >> 16; + ps->options2 = ifa->oa->options >> 8; + ps->options = ifa->oa->options; + ps->helloint = ntohs(ifa->helloint); + ps->deadint = htons(ifa->deadint); + ps->dr = htonl(ifa->drid); + ps->bdr = htonl(ifa->bdrid); + + length = sizeof(struct ospf_hello3_packet); + neighbors = ps->neighbors; + } - /* Fill all neighbors */ i = 0; + max = (ospf_pkt_bufsize(ifa) - length) / sizeof(u32); + /* Fill all neighbors */ if (kind != OHS_SHUTDOWN) { - u32 *pp = (u32 *) (((u8 *) pkt) + sizeof(struct ospf_hello_packet)); WALK_LIST(neigh, ifa->neigh_list) { - if ((i+1) * sizeof(u32) + sizeof(struct ospf_hello_packet) > ospf_pkt_bufsize(ifa)) + if (i == max) { log(L_WARN "%s: Too many neighbors on interface %s", p->name, ifa->iface->name); break; diff --cc proto/ospf/iface.c index 10f87e51f,aa7f78927..cfd2219a7 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@@ -558,8 -565,10 +558,10 @@@ ospf_iface_new(struct ospf_area *oa, st if (ifa->type != old_type) log(L_WARN "%s: Cannot use interface %s as %s, forcing %s", - p->name, iface->name, ospf_it[old_type], ospf_it[ifa->type]); + po->proto.name, iface->name, ospf_it[old_type], ospf_it[ifa->type]); + /* Assign iface ID, for vlinks, this is ugly hack */ + ifa->iface_id = (ifa->type != OSPF_IT_VLINK) ? iface->index : oa->po->last_vlink_id++; init_list(&ifa->neigh_list); init_list(&ifa->nbma_list); diff --cc proto/ospf/lsalib.c index 51a407459,bcf7bcddd..f2857c601 --- a/proto/ospf/lsalib.c +++ b/proto/ospf/lsalib.c @@@ -135,95 -144,6 +135,98 @@@ lsa_ntoh_body(void *n, void *h, u16 len } #endif /* little endian */ + + +int +lsa_flooding_allowed(u32 type, u32 domain, struct ospf_iface *ifa) - { ++{ ++ /* Handle inactive vlinks */ ++ if (ifa->state == OSPF_IS_DOWN) ++ return 0; ++ + /* 4.5.2 (Case 2) */ - + switch (LSA_SCOPE(type)) + { + case LSA_SCOPE_LINK: - return ifa->iface->index == domain; ++ return ifa->iface_id == domain; + + case LSA_SCOPE_AREA: + return ifa->oa->areaid == domain; + + case LSA_SCOPE_AS: + if (ifa->type == OSPF_IT_VLINK) + return 0; + if (!oa_is_ext(ifa->oa)) + return 0; + return 1; + + default: + log(L_ERR "OSPF: LSA with invalid scope"); + return 0; + } +} + + +static int +unknown_lsa_type(u32 type) +{ + switch (type) + { + case LSA_T_RT: + case LSA_T_NET: + case LSA_T_SUM_NET: + case LSA_T_SUM_RT: + case LSA_T_EXT: + case LSA_T_NSSA: + case LSA_T_LINK: + case LSA_T_PREFIX: + return 0; + + default: + return 1; + } +} + +#define LSA_V2_TMAX 8 +static const u16 lsa_v2_types[LSA_V2_TMAX] = + {0, LSA_T_RT, LSA_T_NET, LSA_T_SUM_NET, LSA_T_SUM_RT, LSA_T_EXT, 0, LSA_T_NSSA}; + +void +lsa_xxxxtype(u32 itype, struct ospf_iface *ifa, u32 *otype, u32 *domain) +{ + if (ospf_is_v2(ifa->oa->po)) + { + itype = itype & LSA_T_V2_MASK; + itype = (itype < LSA_V2_TMAX) ? lsa_v2_types[itype] : 0; + } + else + { + /* For unkown LSAs without U-bit change scope to LSA_SCOPE_LINK */ + if (unknown_lsa_type(itype) && !(itype & LSA_UBIT)) + itype = itype & ~LSA_SCOPE_MASK; + } + + *otype = itype; + + switch (LSA_SCOPE(itype)) + { + case LSA_SCOPE_LINK: - *domain = ifa->iface->index; ++ *domain = ifa->iface_id; + return; + + case LSA_SCOPE_AREA: + *domain = ifa->oa->areaid; + return; + + case LSA_SCOPE_AS: + default: + *domain = 0; + return; + } +} + + + /* void buf_dump(const char *hdr, const byte *buf, int blen) diff --cc proto/ospf/lsupd.c index 80c9b0b2e,a5da4251d..94e1b743b --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@@ -93,7 -67,82 +93,6 @@@ static void ospf_lsupd_dump(struct prot } } - -#ifdef OSPFv2 - -int -ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_iface *ifa) -{ - if (lsa->type == LSA_T_EXT) - { - if (ifa->type == OSPF_IT_VLINK) - return 0; - if (!oa_is_ext(ifa->oa)) - return 0; - return 1; - } - else - return ifa->oa->areaid == domain; -} - -#else /* OSPFv3 */ - -static int -unknown_lsa_type(struct ospf_lsa_header *lsa) -{ - switch (lsa->type) - { - case LSA_T_RT: - case LSA_T_NET: - case LSA_T_SUM_NET: - case LSA_T_SUM_RT: - case LSA_T_EXT: - case LSA_T_NSSA: - case LSA_T_LINK: - case LSA_T_PREFIX: - return 0; - - default: - return 1; - } -} - -int -ospf_lsa_flooding_allowed(struct ospf_lsa_header *lsa, u32 domain, struct ospf_iface *ifa) -{ - u32 scope = LSA_SCOPE(lsa); - - /* Handle inactive vlinks */ - if (ifa->state == OSPF_IS_DOWN) - return 0; - - /* 4.5.2 (Case 2) */ - if (unknown_lsa_type(lsa) && !(lsa->type & LSA_UBIT)) - scope = LSA_SCOPE_LINK; - - switch (scope) - { - case LSA_SCOPE_LINK: - return ifa->iface_id == domain; - - case LSA_SCOPE_AREA: - return ifa->oa->areaid == domain; - - case LSA_SCOPE_AS: - if (ifa->type == OSPF_IT_VLINK) - return 0; - if (!oa_is_ext(ifa->oa)) - return 0; - return 1; - - default: - log(L_ERR "LSA with invalid scope"); - return 0; - } -} - -#endif -- /** * ospf_lsupd_flood - send received or generated lsa to the neighbors * @po: OSPF protocol diff --cc proto/ospf/neighbor.c index 118919d49,26d81dceb..228e02d28 --- a/proto/ospf/neighbor.c +++ b/proto/ospf/neighbor.c @@@ -442,9 -453,14 +442,9 @@@ bdr_election(struct ospf_iface *ifa me.priority = ifa->priority; me.ip = ifa->addr->ip; -#ifdef OSPFv2 - me.dr = ipa_to_u32(ifa->drip); - me.bdr = ipa_to_u32(ifa->bdrip); -#else /* OSPFv3 */ - me.dr = ifa->drid; - me.bdr = ifa->bdrid; + me.dr = ospf_is_v2(po) ? ipa_to_u32(ifa->drip) : ifa->drid; + me.bdr = ospf_is_v2(po) ? ipa_to_u32(ifa->bdrip) : ifa->bdrid; - me.iface_id = ifa->iface->index; + me.iface_id = ifa->iface_id; -#endif add_tail(&ifa->neigh_list, NODE & me); diff --cc proto/ospf/ospf.c index 9a7eaa63b,6654e107c..0b5de651b --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@@ -935,70 -949,80 +936,85 @@@ static int lsa_compare_ospf3 static int lsa_compare_for_state(const void *p1, const void *p2) { - struct top_hash_entry * he1 = * (struct top_hash_entry **) p1; - struct top_hash_entry * he2 = * (struct top_hash_entry **) p2; + struct top_hash_entry *he1 = * (struct top_hash_entry **) p1; + struct top_hash_entry *he2 = * (struct top_hash_entry **) p2; struct ospf_lsa_header *lsa1 = &(he1->lsa); struct ospf_lsa_header *lsa2 = &(he2->lsa); + struct ospf_lsa_header lsatmp1, lsatmp2; + u16 lsa1_type = he1->lsa_type; + u16 lsa2_type = he2->lsa_type; - if (he1->domain != he2->domain) - return he1->domain - he2->domain; + if (he1->domain < he2->domain) + return -1; + if (he1->domain > he2->domain) + return 1; -#ifdef OSPFv3 - struct ospf_lsa_header lsatmp1, lsatmp2; - int px1 = (lsa1->type == LSA_T_PREFIX); - int px2 = (lsa2->type == LSA_T_PREFIX); + /* px1 or px2 assumes OSPFv3 */ + int px1 = (lsa1_type == LSA_T_PREFIX); + int px2 = (lsa2_type == LSA_T_PREFIX); if (px1) + { lsa1 = fake_lsa_from_prefix_lsa(&lsatmp1, lsa1, he1->lsa_body); + lsa1_type = lsa1->type_raw; /* FIXME: handle unknown ref_type */ + } if (px2) + { lsa2 = fake_lsa_from_prefix_lsa(&lsatmp2, lsa2, he2->lsa_body); -#endif + lsa2_type = lsa2->type_raw; + } - int nt1 = (lsa1->type == LSA_T_NET); - int nt2 = (lsa2->type == LSA_T_NET); + + int nt1 = (lsa1_type == LSA_T_NET); + int nt2 = (lsa2_type == LSA_T_NET); if (nt1 != nt2) return nt1 - nt2; if (nt1) { -#ifdef OSPFv3 - /* In OSPFv3, neworks are named base on ID of DR */ - if (lsa1->rt < lsa2->rt) - return -1; - if (lsa1->rt > lsa2->rt) - return 1; -#endif + /* In OSPFv3, networks are named based on ID of DR */ - if (lsa_compare_ospf3 && (lsa1->rt != lsa2->rt)) - return lsa1->rt - lsa2->rt; ++ if (lsa_compare_ospf3) ++ { ++ if (lsa1->rt < lsa2->rt) ++ return -1; ++ if (lsa1->rt > lsa2->rt) ++ return 1; ++ } /* For OSPFv2, this is IP of the network, for OSPFv3, this is interface ID */ - if (lsa1->id != lsa2->id) - return lsa1->id - lsa2->id; + if (lsa1->id < lsa2->id) + return -1; + if (lsa1->id > lsa2->id) + return 1; -#ifdef OSPFv3 if (px1 != px2) return px1 - px2; -#endif return lsa1->sn - lsa2->sn; } else { - if (lsa1->rt != lsa2->rt) - return lsa1->rt - lsa2->rt; + if (lsa1->rt < lsa2->rt) + return -1; + if (lsa1->rt > lsa2->rt) + return 1; - if (lsa1_type != lsa2_type) - return lsa1_type - lsa2_type; - - if (lsa1->id != lsa2->id) - return lsa1->id - lsa2->id; - if (lsa1->type < lsa2->type) ++ if (lsa1_type < lsa2_type) + return -1; - if (lsa1->type > lsa2->type) ++ if (lsa1_type > lsa2_type) + return 1; + + if (lsa1->id < lsa2->id) + return -1; + if (lsa1->id > lsa2->id) + return 1; -#ifdef OSPFv3 if (px1 != px2) return px1 - px2; -#endif return lsa1->sn - lsa2->sn; } diff --cc proto/ospf/topology.c index 91b7810ab,177cd53ac..ea1e8f1b7 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@@ -262,8 -255,13 +262,8 @@@ originate_rt2_lsa_body(struct ospf_are WALK_LIST(neigh, ifa->neigh_list) if (neigh->state == NEIGHBOR_FULL) { - u32 data = (ifa->addr->flags & IA_PEER) ? ifa->iface->index : ipa_to_u32(ifa->addr->ip); - ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link)); - ln->type = LSART_PTP; - ln->id = neigh->rid; - ln->data = (ifa->addr->flags & IA_PEER) ? - ifa->iface_id : ipa_to_u32(ifa->addr->ip); - ln->metric = ifa->cost; - ln->padding = 0; ++ u32 data = (ifa->addr->flags & IA_PEER) ? ifa->iface_id : ipa_to_u32(ifa->addr->ip); + add_rt2_lsa_link(po, LSART_PTP, neigh->rid, data, ifa->cost); i++; } break; @@@ -514,10 -545,11 +514,10 @@@ originate_net3_lsa_body(struct proto_os { if (n->state == NEIGHBOR_FULL) { -#ifdef OSPFv3 + /* In OSPFv3, we would like to merge options from Link LSAs of added neighbors */ - en = ospf_hash_find(po->gr, ifa->iface->index, n->iface_id, n->rid, LSA_T_LINK); + en = ospf_hash_find(po->gr, ifa->iface_id, n->iface_id, n->rid, LSA_T_LINK); if (en) options |= ((struct ospf_lsa_link *) en->lsa_body)->options; -#endif net->routers[i] = n->rid; i++; @@@ -560,13 -590,19 +560,13 @@@ originate_net_lsa(struct ospf_iface *if ifa->iface->name); lsa.age = 0; - lsa.type = LSA_T_NET; - -#ifdef OSPFv2 - lsa.options = ifa->oa->options; - lsa.id = ipa_to_u32(ifa->addr->ip); -#else /* OSPFv3 */ - lsa.id = ifa->iface_id; -#endif - + lsa.type_raw = LSA_T_NET; - lsa.id = ospf_is_v2(po) ? ipa_to_u32(ifa->addr->ip) : ifa->iface->index; ++ lsa.id = ospf_is_v2(po) ? ipa_to_u32(ifa->addr->ip) : ifa->iface_id; lsa.rt = po->router_id; lsa.sn = get_seqnum(ifa->net_lsa); + lsa_fix_options(po, &lsa, ifa->oa->options); - body = originate_net_lsa_body(ifa, &lsa.length, po); + body = originate_net_lsa_body(po, ifa, &lsa.length); lsasum_calculate(&lsa, body); ifa->net_lsa = lsa_install_new(po, &lsa, dom, body); ospf_lsupd_flood(po, NULL, NULL, &lsa, dom, 1); @@@ -1183,19 -1197,20 +1183,19 @@@ originate_link_lsa_body(struct ospf_ifa void originate_link_lsa(struct ospf_iface *ifa) { - struct ospf_lsa_header lsa; struct proto_ospf *po = ifa->oa->po; - struct proto *p = &po->proto; + struct ospf_lsa_header lsa; - u32 dom = ifa->iface->index; ++ u32 dom = ifa->iface_id; void *body; /* FIXME check for vlink and skip that? */ OSPF_TRACE(D_EVENTS, "Originating link-LSA for iface %s", ifa->iface->name); lsa.age = 0; - lsa.type = LSA_T_LINK; + lsa.type_raw = LSA_T_LINK; - lsa.id = ifa->iface->index; + lsa.id = ifa->iface_id; lsa.rt = po->router_id; lsa.sn = get_seqnum(ifa->link_lsa); - u32 dom = ifa->iface_id; body = originate_link_lsa_body(ifa, &lsa.length); lsasum_calculate(&lsa, body); @@@ -1464,10 -1492,11 +1486,10 @@@ originate_prefix_net_lsa(struct ospf_if ifa->iface->name); lsa.age = 0; - lsa.type = LSA_T_PREFIX; + lsa.type_raw = LSA_T_PREFIX; - lsa.id = ifa->iface->index; + lsa.id = ifa->iface_id; lsa.rt = po->router_id; lsa.sn = get_seqnum(ifa->pxn_lsa); - u32 dom = ifa->oa->areaid; body = originate_prefix_net_lsa_body(ifa, &lsa.length); lsasum_calculate(&lsa, body);