diff --git a/nest/iface.c b/nest/iface.c index 19b19ed5..3cfc626a 100644 --- a/nest/iface.c +++ b/nest/iface.c @@ -51,7 +51,7 @@ ifa_dump(struct ifa *a) debug("\t%I, net %I/%-2d bc %I -> %I%s%s%s\n", a->ip, a->prefix, a->pxlen, a->brd, a->opposite, (a->flags & IF_UP) ? "" : " DOWN", (a->flags & IA_PRIMARY) ? "" : " SEC", - (a->flags & IA_UNNUMBERED) ? " UNNUM" : ""); + (a->flags & IA_PEER) ? "PEER" : ""); } /** @@ -474,7 +474,7 @@ ifa_update(struct ifa *a) ipa_equal(b->brd, a->brd) && ipa_equal(b->opposite, a->opposite) && b->scope == a->scope && - !((b->flags ^ a->flags) & IA_UNNUMBERED)) + !((b->flags ^ a->flags) & IA_PEER)) { b->flags |= IF_UPDATED; return b; @@ -543,7 +543,7 @@ auto_router_id(void) if ((i->flags & IF_ADMIN_UP) && !(i->flags & (IF_IGNORE | IF_SHUTDOWN)) && i->addr && - !(i->addr->flags & IA_UNNUMBERED) && + !(i->addr->flags & IA_PEER) && (!j || ipa_to_u32(i->addr->ip) < ipa_to_u32(j->addr->ip))) j = i; if (!j) @@ -602,7 +602,7 @@ iface_patt_match(struct iface_patt *ifp, struct iface *i, struct ifa *a) if (ipa_in_net(a->ip, p->prefix, p->pxlen)) return pos; - if ((a->flags & IA_UNNUMBERED) && + if ((a->flags & IA_PEER) && ipa_in_net(a->opposite, p->prefix, p->pxlen)) return pos; @@ -671,23 +671,16 @@ iface_patts_equal(list *a, list *b, int (*comp)(struct iface_patt *, struct ifac static void if_show_addr(struct ifa *a) { - byte broad[STD_ADDRESS_P_LENGTH + 16]; byte opp[STD_ADDRESS_P_LENGTH + 16]; - if (ipa_nonzero(a->brd)) - bsprintf(broad, ", broadcast %I", a->brd); - else - broad[0] = 0; if (ipa_nonzero(a->opposite)) bsprintf(opp, ", opposite %I", a->opposite); else opp[0] = 0; - cli_msg(-1003, "\t%I/%d (%s%s%s, scope %s%s)", + cli_msg(-1003, "\t%I/%d (%s%s, scope %s)", a->ip, a->pxlen, (a->flags & IA_PRIMARY) ? "Primary" : (a->flags & IA_SECONDARY) ? "Secondary" : "Unselected", - broad, opp, - ip_scope_text(a->scope), - (a->flags & IA_UNNUMBERED) ? ", unnumbered" : ""); + opp, ip_scope_text(a->scope)); } void diff --git a/nest/iface.h b/nest/iface.h index 6b47a620..5906e218 100644 --- a/nest/iface.h +++ b/nest/iface.h @@ -51,9 +51,23 @@ struct iface { #define IA_PRIMARY 0x10000 /* This address is primary */ #define IA_SECONDARY 0x20000 /* This address has been reported as secondary by the kernel */ -#define IA_UNNUMBERED 0x40000 /* This address belongs to an unnumbered device */ +#define IA_PEER 0x40000 /* A peer/ptp address */ +#define IA_HOST 0x80000 /* A host/loopback address */ #define IA_FLAGS 0xff0000 +/* + * There are three kinds of addresses in BIRD: + * - Standard (prefix-based) addresses, these may define ifa.opposite (for /30 or /31). + * - Peer/ptp addresses, without common prefix for ifa.ip and ifa.opposite. + * ifa.opposite is defined and ifa.prefix/pxlen == ifa.opposite/32 (for simplicity). + * - Host addresses, with ifa.prefix/pxlen == ifa.ip/32 (or /128). + * May be considered a special case of standard addresses. + * + * Peer addresses (AFAIK) do not exist in IPv6. Linux alos supports generalized peer + * address (with pxlen < 32 and ifa.ip outside prefix), we do not support that. + */ + + #define IF_JUST_CREATED 0x10000000 /* Send creation event as soon as possible */ #define IF_TMP_DOWN 0x20000000 /* Temporary shutdown due to interface reconfiguration */ #define IF_UPDATED 0x40000000 /* Touched in last scan */ @@ -85,15 +99,6 @@ struct iface *if_find_by_index(unsigned); struct iface *if_find_by_name(char *); void ifa_recalc_all_primary_addresses(void); -static inline int -ifa_match_addr(struct ifa *ifa, ip_addr addr) -{ - if (ifa->flags & IA_UNNUMBERED) - return ipa_equal(addr, ifa->opposite); - else - return ipa_in_net(addr, ifa->prefix, ifa->pxlen); -} - /* The Neighbor Cache */ typedef struct neighbor { diff --git a/nest/neighbor.c b/nest/neighbor.c index 1e0780c1..1a5ac215 100644 --- a/nest/neighbor.c +++ b/nest/neighbor.c @@ -66,7 +66,7 @@ if_connected(ip_addr *a, struct iface *i) /* -1=error, 1=match, 0=no match */ { if (ipa_equal(*a, b->ip)) return SCOPE_HOST; - if (b->flags & IA_UNNUMBERED) + if (b->flags & IA_PEER) { if (ipa_equal(*a, b->opposite)) return b->scope; diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index faee634a..78899448 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -443,6 +443,10 @@ ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr) if (! addr) return 0; + /* a host/loopback address */ + if (addr->flags & IA_HOST) + return 1; + /* * We cannot properly support multiple OSPF ifaces on real iface * with multiple prefixes, therefore we force OSPF ifaces with @@ -453,10 +457,6 @@ ospf_iface_stubby(struct ospf_iface_patt *ip, struct ifa *addr) return 1; #endif - /* a loopback/dummy address */ - if ((addr->pxlen == MAX_PREFIX_LENGTH) && ipa_zero(addr->opposite)) - return 1; - return ip->stub; } @@ -522,10 +522,10 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i int old_type = ifa->type; #ifdef OSPFv2 - if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_UNNUMBERED)) + if ((ifa->type == OSPF_IT_BCAST) && (addr->flags & IA_PEER)) ifa->type = OSPF_IT_PTP; - if ((ifa->type == OSPF_IT_NBMA) && (addr->flags & IA_UNNUMBERED)) + if ((ifa->type == OSPF_IT_NBMA) && (addr->flags & IA_PEER)) ifa->type = OSPF_IT_PTMP; #endif @@ -1115,7 +1115,7 @@ ospf_iface_info(struct ospf_iface *ifa) else { #ifdef OSPFv2 - if (ifa->addr->flags & IA_UNNUMBERED) + if (ifa->addr->flags & IA_PEER) cli_msg(-1015, "Interface %s (peer %I)", ifa->iface->name, ifa->addr->opposite); else cli_msg(-1015, "Interface %s (%I/%d)", ifa->iface->name, ifa->addr->prefix, ifa->addr->pxlen); diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index e8ebafd8..ae9f862a 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -269,7 +269,7 @@ ospf_rx_hook(sock *sk, int size) struct proto_ospf *po = ifa->oa->po; // struct proto *p = &po->proto; - int src_local = ifa_match_addr(ifa->addr, sk->faddr); + int src_local = ipa_in_net(sk->faddr, ifa->addr->prefix, ifa->addr->pxlen); int dst_local = ipa_equal(sk->laddr, ifa->addr->ip); int dst_mcast = ipa_equal(sk->laddr, AllSPFRouters) || ipa_equal(sk->laddr, AllDRouters); diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c index 1403e72e..78d88592 100644 --- a/proto/ospf/topology.c +++ b/proto/ospf/topology.c @@ -160,6 +160,7 @@ configured_stubnet(struct ospf_area *oa, struct ifa *a) if (!oa->ac) return 0; + /* Does not work for IA_PEER addresses, but it is not called on these */ struct ospf_stubnet_config *sn; WALK_LIST(sn, oa->ac->stubnet_list) { @@ -254,7 +255,7 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length) ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link)); ln->type = LSART_PTP; ln->id = neigh->rid; - ln->data = (ifa->addr->flags & IA_UNNUMBERED) ? + ln->data = (ifa->addr->flags & IA_PEER) ? ifa->iface->index : ipa_to_u32(ifa->addr->ip); ln->metric = ifa->cost; ln->padding = 0; @@ -301,12 +302,14 @@ originate_rt_lsa_body(struct ospf_area *oa, u16 *length) /* Now we will originate stub area if there is no primary */ if (net_lsa || (ifa->type == OSPF_IT_VLINK) || - (ifa->addr->flags & IA_UNNUMBERED) || + (ifa->addr->flags & IA_PEER) || configured_stubnet(oa, ifa->addr)) continue; ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link)); - if ((ifa->state == OSPF_IS_LOOP) || (ifa->type == OSPF_IT_PTMP)) + if ((ifa->addr->flags & IA_HOST) || + (ifa->state == OSPF_IS_LOOP) || + (ifa->type == OSPF_IT_PTMP)) { /* Host stub entry */ ln->type = LSART_STUB; @@ -1208,7 +1211,7 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length) WALK_LIST(a, ifa->iface->addrs) { if ((a->flags & IA_SECONDARY) || - (a->flags & IA_UNNUMBERED) || + (a->flags & IA_PEER) || (a->scope <= SCOPE_LINK)) continue; @@ -1219,15 +1222,16 @@ originate_prefix_rt_lsa_body(struct ospf_area *oa, u16 *length) configured_stubnet(oa, a)) continue; - if ((ifa->state == OSPF_IS_LOOP) || (ifa->type == OSPF_IT_PTMP)) + if ((a->flags & IA_HOST) || + (ifa->state == OSPF_IS_LOOP) || + (ifa->type == OSPF_IT_PTMP)) + { lsa_put_prefix(po, a->ip, MAX_PREFIX_LENGTH, 0); + host_addr = 1; + } else lsa_put_prefix(po, a->prefix, a->pxlen, ifa->cost); i++; - - if ((ifa->state == OSPF_IS_LOOP) || - (a->pxlen == MAX_PREFIX_LENGTH)) - host_addr = 1; } ifa->px_pos_end = i; diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 4b3de2ea..0259cfb5 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -704,7 +704,7 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_ } if (new) { - if (new->addr->flags & IA_UNNUMBERED) + if (new->addr->flags & IA_PEER) log( L_WARN "%s: rip is not defined over unnumbered links", p->name ); if (rif->multicast) { #ifndef IPV6 diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index a3e17e27..a4df52ee 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -543,6 +543,9 @@ krt_read_addr(struct ks_msg *msg) { ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen)); + if (masklen == BITS_PER_IP_ADDRESS) + ifa.flags |= IA_HOST; + if (masklen == (BITS_PER_IP_ADDRESS - 1)) ifa.opposite = ipa_opposite_m1(ifa.ip); @@ -553,7 +556,7 @@ krt_read_addr(struct ks_msg *msg) } else /* PtP iface */ { - ifa.flags |= IA_UNNUMBERED; + ifa.flags |= IA_PEER; ifa.prefix = ifa.opposite = ifa.brd; } diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c index 3eaa53ae..afca626d 100644 --- a/sysdep/linux/netlink/netlink.c +++ b/sysdep/linux/netlink/netlink.c @@ -499,10 +499,12 @@ nl_parse_addr(struct nlmsghdr *h) ipa_ntoh(addr); ifa.prefix = ifa.brd = addr; - /* It is either a peer address, or loopback/dummy address */ - if (!ipa_equal(ifa.ip, addr)) + /* It is either a host address or a peer address */ + if (ipa_equal(ifa.ip, addr)) + ifa.flags |= IA_HOST; + else { - ifa.flags |= IA_UNNUMBERED; + ifa.flags |= IA_PEER; ifa.opposite = addr; } } diff --git a/sysdep/unix/krt-iface.c b/sysdep/unix/krt-iface.c index c305d27a..69048ae8 100644 --- a/sysdep/unix/krt-iface.c +++ b/sysdep/unix/krt-iface.c @@ -98,7 +98,7 @@ scan_ifs(struct ifreq *r, int cnt) if (fl & IFF_POINTOPOINT) { - a.flags |= IA_UNNUMBERED; + a.flags |= IA_PEER; if (ioctl(if_scan_sock, SIOCGIFDSTADDR, r) < 0) { err = "SIOCGIFDSTADDR"; goto faulty; } get_sockaddr((struct sockaddr_in *) &r->ifr_addr, &a.opposite, NULL, 1); @@ -114,7 +114,7 @@ scan_ifs(struct ifreq *r, int cnt) && (fl & IFF_MULTICAST) #endif #ifndef CONFIG_UNNUM_MULTICAST - && !(a.flags & IA_UNNUMBERED) + && !(a.flags & IA_PEER) #endif ) i.flags |= IF_MULTICAST;