On Fri, May 31, 2013 at 02:30:09PM +0200, Claudio Jeker wrote: > On Thu, May 30, 2013 at 11:51:24PM +0200, Stijn wrote: > > Hi misc, > > > > I've been playing with OSPF on OpenBSD and Cisco and there's > > something I can't get my head around. I hope someone is able to > > point my in the right direction. > > > > Let me first explain the setup; output of the devices follows at the end. > > > > I have a setup of two Cisco routers (IOS 12.4.25g) and one OpenBSD > > router (5.3 i386). All routers have an interface connected to area > > 0. The interfaces are defined as follows: > > router1: fa0/0, 10.0.0.1/24 > > router2: fa0/0, 10.0.0.2/24 > > soekris: sis1, 10.0.0.3/24 > > > > Each router also have a loopback interface: > > router1: lo1, 1.1.1.1 > > router2: lo1, 2.2.2.2 > > soekris: lo1, 3.3.3.3 > > > > On the "other" side of the routers I have defined a dedicated > > areafor each router: > > router1: area 0.0.0.1 > > router2: area 0.0.0.2 > > soekris: area 0.0.0.3 > > > > In the dedicated area I've added the following interface: > > router1: vlan101, 10.101.0.1/24 > > router2: vlan102, 10.102.0.1/24 > > soekris: sis2, 10.103.0.1/24 > > > > When I start ospfd, all routers are able to see each other. On > > soekris I'm also able to see the networks from the areas behind > > router1 and router2: > > ---- > > soekris:~# ospfctl sh nei > > ID Pri State DeadTime Address Iface Uptime > > 1.1.1.1 1 FULL/BCKUP 00:00:00 10.0.0.1 sis0 00:21:48 > > 2.2.2.2 1 FULL/DR 00:00:00 10.0.0.2 sis0 00:21:43 > > ---- > > soekris:~# ospfctl sh fib ospf > > flags: * = valid, O = OSPF, C = Connected, S = Static > > Flags Prio Destination Nexthop > > *O 32 1.1.1.1/32 10.0.0.1 > > *O 32 2.2.2.2/32 10.0.0.2 > > *O 32 10.0.0.0/24 10.0.0.3 > > *O 32 10.101.0.0/24 10.0.0.1 > > *O 32 10.102.0.0/24 10.0.0.2 > > ---- > > > > However on the Cisco routers I'm not able to see the dedicated > > network behind soekris: > > ---- > > router1#sh ip route ospf > > 2.0.0.0/32 is subnetted, 1 subnets > > O 2.2.2.2 [110/2] via 10.0.0.2, 00:21:48, FastEthernet0/0 > > 3.0.0.0/32 is subnetted, 1 subnets > > O 3.3.3.3 [110/11] via 10.0.0.3, 00:21:48, FastEthernet0/0 > > 10.0.0.0/24 is subnetted, 3 subnets > > O IA 10.102.0.0 [110/2] via 10.0.0.2, 00:21:48, FastEthernet0/0 > > ---- > > > > When I add a secondary OpenBSD router (eeepc) behind soekris in area > > 0.0.0.3 (as a stub router) the networks in area 0.0.0.3 are shown on > > the Cisco routers (eeepc has 4.4.4.4 as loopback interface): > > ---- > > router1#sh ip route ospf > > 2.0.0.0/32 is subnetted, 1 subnets > > O 2.2.2.2 [110/2] via 10.0.0.2, 00:00:16, FastEthernet0/0 > > 3.0.0.0/32 is subnetted, 1 subnets > > O 3.3.3.3 [110/11] via 10.0.0.3, 00:00:16, FastEthernet0/0 > > 4.0.0.0/32 is subnetted, 1 subnets > > O IA 4.4.4.4 [110/21] via 10.0.0.3, 00:00:06, FastEthernet0/0 > > 10.0.0.0/24 is subnetted, 4 subnets > > O IA 10.102.0.0 [110/2] via 10.0.0.2, 00:00:16, FastEthernet0/0 > > O IA 10.103.0.0 [110/11] via 10.0.0.3, 00:00:16, FastEthernet0/0 > > ---- > > > > I've seen on the Cisco routers the following that might point to the > > cause of the issue(?) When eeepc is not active the Cisco router > > shows soekris as "ASBR": > > ---- > > router1#sh ip ospf border-routers > > > > OSPF Process 1 internal Routing Table > > > > Codes: i - Intra-area route, I - Inter-area route > > > > i 2.2.2.2 [1] via 10.0.0.2, FastEthernet0/0, ABR, Area 0, SPF 37 > > i 3.3.3.3 [1] via 10.0.0.3, FastEthernet0/0, ASBR, Area 0, SPF 37 > > ---- > > > > When eeepc is active the Cisco shows soekris as "ASR/ASBR" and > > routes from area 0.0.0.3 are available on the Cisco routers: > > ---- > > router1#sh ip ospf border-routers > > > > OSPF Process 1 internal Routing Table > > > > Codes: i - Intra-area route, I - Inter-area route > > > > i 2.2.2.2 [1] via 10.0.0.2, FastEthernet0/0, ABR, Area 0, SPF 36 > > i 3.3.3.3 [1] via 10.0.0.3, FastEthernet0/0, ABR/ASBR, Area 0, SPF 36 > > ---- > > > > So, now my question is: how can I get soekris to be seen as an ABR > > without using eeepc? Is it because the Cisco routers see soekris as > > an ASBR that they don't add 10.103.0.0/24 and 4.4.4.4/32 to their > > routing table? I also played with the rfc1583 compatibility mode but > > without luck. > > > > Anybody have a clue how to solve this? Please let me know if you > > need any other output. > > > > Thanks in advance, > > Stijn > > > > Here's the output of the ospf config and interfaces. > > > > router1: > > ---- > > router ospf 1 > > router-id 1.1.1.1 > > no compatible rfc1583 > > log-adjacency-changes > > passive-interface Vlan101 > > network 1.1.1.1 0.0.0.0 area 0 > > network 10.0.0.0 0.0.0.255 area 0 > > network 10.101.0.0 0.0.0.255 area 1 > > > > interface FastEthernet0/0 > > ip address 10.0.0.1 255.255.255.0 > > ip ospf authentication message-digest > > ip ospf message-digest-key 1 md5 7 130A04020D5C > > ip ospf dead-interval minimal hello-multiplier 5 > > duplex auto > > speed auto > > end > > ---- > > > > router2: > > ---- > > router ospf 1 > > router-id 2.2.2.2 > > no compatible rfc1583 > > log-adjacency-changes > > passive-interface Vlan102 > > network 2.2.2.2 0.0.0.0 area 0 > > network 10.0.0.0 0.0.0.255 area 0 > > network 10.1.0.0 0.0.0.255 area 0 > > network 10.102.0.0 0.0.0.255 area 2 > > > > interface FastEthernet0/0 > > ip address 10.0.0.2 255.255.255.0 > > ip ospf authentication message-digest > > ip ospf message-digest-key 1 md5 7 0504151F271C > > ip ospf dead-interval minimal hello-multiplier 5 > > duplex auto > > speed auto > > end > > ---- > > > > soekris: > > ---- > > soekris:~# ifconfig sis0 > > sis0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 > > lladdr 00:00:24:c5:ef:9c > > priority: 0 > > media: Ethernet autoselect (100baseTX full-duplex) > > status: active > > inet 10.0.0.3 netmask 0xffffff00 broadcast 10.0.0.255 > > inet6 fe80::200:24ff:fec5:ef9c%sis0 prefixlen 64 scopeid 0x1 > > ---- > > soekris:~# cat /etc/ospfd.conf > > # $OpenBSD: ospfd.conf,v 1.4 2007/06/19 16:49:56 reyk Exp $ > > > > # macros > > > > # global configuration > > router-id 3.3.3.3 > > redistribute connected > > fast-hello-interval msec 200 > > router-dead-time minimal > > router-priority 3 > > rfc1583compat no > > > > # areas > > area 0.0.0.0 { > > interface sis0 { > > auth-type crypt > > auth-md 1 "ospf0" > > auth-md-keyid 1 > > } > > interface sis1 { > > auth-type crypt > > auth-md 1 "ospf1" > > auth-md-keyid 1 > > } > > interface lo1 { > > passive > > } > > } > > area 0.0.0.3 { > > # stub redistribute default > > interface sis2 { > > auth-type crypt > > auth-md 1 "ospf2" > > auth-md-keyid 1 > > } > > } > > ---- > > eeepc: > > ---- > > eeepc:~# cat /etc/ospfd.conf > > # global configuration > > router-id 4.4.4.4 > > fast-hello-interval msec 200 > > router-dead-time minimal > > router-priority 0 > > rfc1583compat no > > > > # areas > > area 0.0.0.3 { > > # stub > > interface lii0 { > > auth-type crypt > > auth-md 1 "ospf2" > > auth-md-keyid 1 > > } > > interface lo1 { > > passive > > } > > } > > > > FYI, eeepc is started as a stub router automatically because IP > > forwarding is not enabled. > > Thanks for the detailed report. I remember something about the ABR flag > being only set if there is another router active in the area. There was > something about that in the RFC but maybe my memory is wrong. > > I add it to my list of things to looks at during the hackathon.
Can you give this diff a spin? Not much tested but the current way we define an area as active (having at least one active neighbor) is wrong. This changes the decision to have at least one active interface (not IF_STA_DOWN). Not sure if that will cause troubles with passive interfaces since those are not considered active. At least it seems that RFC 3509 uses this to define active areas. Thanks -- :wq Claudio Index: area.c =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/area.c,v retrieving revision 1.9 diff -u -p -r1.9 area.c --- area.c 7 Jan 2009 21:16:36 -0000 1.9 +++ area.c 1 Jun 2013 15:33:48 -0000 @@ -94,19 +94,24 @@ area_find(struct ospfd_conf *conf, struc } void -area_track(struct area *area, int state) +area_track(struct area *area) { - int old = area->active; + int old = area->active; + struct iface *iface; - if (state & NBR_STA_FULL) - area->active++; - else if (area->active == 0) - fatalx("area_track: area already inactive"); - else - area->active--; + area->active = 0; + LIST_FOREACH(iface, &area->iface_list, entry) { + if (iface->state & IF_STA_DOWN) + continue; + area->active = 1; + break; + } - if (area->active == 0 || old == 0) + if (area->active != old) { + ospfe_imsg_compose_rde(IMSG_AREA_CHANGE, area->id.s_addr, 0, + &area->active, sizeof(area->active)); ospfe_demote_area(area, old == 0); + } } int @@ -116,7 +121,7 @@ area_border_router(struct ospfd_conf *co int active = 0; LIST_FOREACH(area, &conf->area_list, entry) - if (area->active > 0) + if (area->active) active++; return (active > 1); Index: interface.c =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/interface.c,v retrieving revision 1.75 diff -u -p -r1.75 interface.c --- interface.c 14 May 2012 10:17:21 -0000 1.75 +++ interface.c 1 Jun 2013 14:25:24 -0000 @@ -136,8 +136,10 @@ if_fsm(struct iface *iface, enum iface_e if (new_state != 0) iface->state = new_state; - if (iface->state != old_state) + if (iface->state != old_state) { + area_track(iface->area); orig_rtr_lsa(iface->area); + } if (old_state & (IF_STA_MULTI | IF_STA_POINTTOPOINT) && (iface->state & (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0) Index: neighbor.c =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/neighbor.c,v retrieving revision 1.46 diff -u -p -r1.46 neighbor.c --- neighbor.c 17 Jan 2013 10:07:56 -0000 1.46 +++ neighbor.c 1 Jun 2013 14:23:40 -0000 @@ -204,7 +204,6 @@ nbr_fsm(struct nbr *nbr, enum nbr_event * neighbor changed from/to FULL * originate new rtr and net LSA */ - area_track(nbr->iface->area, nbr->state); orig_rtr_lsa(nbr->iface->area); if (nbr->iface->state & IF_STA_DR) orig_net_lsa(nbr->iface); Index: ospfd.h =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/ospfd.h,v retrieving revision 1.91 diff -u -p -r1.91 ospfd.h --- ospfd.h 17 Jan 2013 10:07:56 -0000 1.91 +++ ospfd.h 1 Jun 2013 15:29:30 -0000 @@ -104,6 +104,7 @@ enum imsg_type { IMSG_NEIGHBOR_CAPA, IMSG_NETWORK_ADD, IMSG_NETWORK_DEL, + IMSG_AREA_CHANGE, IMSG_DD, IMSG_DD_END, IMSG_DD_BADLSA, @@ -530,7 +531,7 @@ struct demote_msg { struct area *area_new(void); int area_del(struct area *); struct area *area_find(struct ospfd_conf *, struct in_addr); -void area_track(struct area *, int); +void area_track(struct area *); int area_border_router(struct ospfd_conf *); u_int8_t area_ospf_options(struct area *); Index: ospfe.c =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v retrieving revision 1.86 diff -u -p -r1.86 ospfe.c --- ospfe.c 22 Mar 2013 08:42:55 -0000 1.86 +++ ospfe.c 1 Jun 2013 15:33:53 -0000 @@ -992,9 +992,9 @@ orig_rtr_lsa(struct area *area) oeconf->border = border; orig_rtr_lsa_all(area); } - if (oeconf->border) lsa_rtr.flags |= OSPF_RTR_B; + /* TODO set V flag if a active virtual link ends here and the * area is the transit area for this link. */ if (virtual) Index: rde.c =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/rde.c,v retrieving revision 1.94 diff -u -p -r1.94 rde.c --- rde.c 9 May 2011 12:24:41 -0000 1.94 +++ rde.c 1 Jun 2013 15:35:26 -0000 @@ -296,11 +296,6 @@ rde_dispatch_imsg(int fd, short event, v if (nbr == NULL) break; - if (state != nbr->state && - (nbr->state & NBR_STA_FULL || - state & NBR_STA_FULL)) - area_track(nbr->area, state); - nbr->state = state; if (nbr->state & NBR_STA_FULL) rde_req_list_free(nbr); @@ -312,6 +307,19 @@ rde_dispatch_imsg(int fd, short event, v if (nbr == NULL) break; nbr->capa_options = *(u_int8_t *)imsg.data; + break; + case IMSG_AREA_CHANGE: + if (imsg.hdr.len - IMSG_HEADER_SIZE != sizeof(state)) + fatalx("invalid size of OE request"); + + LIST_FOREACH(area, &rdeconf->area_list, entry) { + if (area->id.s_addr == imsg.hdr.peerid) + break; + } + if (area == NULL) + break; + memcpy(&state, imsg.data, sizeof(state)); + area->active = state; break; case IMSG_DB_SNAPSHOT: nbr = rde_nbr_find(imsg.hdr.peerid);