From 0f3af7386e70d8c88453ad1a4252d116240b1416 Mon Sep 17 00:00:00 2001 From: Juergen Werner Date: Sat, 10 Aug 2019 11:52:03 +0200 Subject: [PATCH] zebra: Do not use connection dest for bcast The `destination` field of the connection structure was used to store the broadcast address, if the connection was not p2p. This multipurpose is not very evident and the benefits over calculating the bcast address on the fly minimal. Signed-off-by: Juergen Werner --- lib/if.h | 6 +-- ospfd/ospf_vty.c | 69 +++++++++++++++++----------------- zebra/connected.c | 88 +++++++++++++++++--------------------------- zebra/connected.h | 8 ++-- zebra/if_netlink.c | 10 +++-- zebra/interface.c | 14 ++----- zebra/zebra_dplane.c | 5 +-- 7 files changed, 82 insertions(+), 118 deletions(-) diff --git a/lib/if.h b/lib/if.h index 603c9c3780..7024d313c6 100644 --- a/lib/if.h +++ b/lib/if.h @@ -383,16 +383,12 @@ struct connected { /* N.B. the ZEBRA_IFA_PEER flag should be set if and only if a peer address has been configured. If this flag is set, the destination field must contain the peer address. - Otherwise, if this flag is not set, the destination address - will either contain a broadcast address or be NULL. */ /* Address of connected network. */ struct prefix *address; - /* Peer or Broadcast address, depending on whether ZEBRA_IFA_PEER is - set. - Note: destination may be NULL if ZEBRA_IFA_PEER is not set. */ + /* Peer address, if ZEBRA_IFA_PEER is set, otherwise NULL */ struct prefix *destination; /* Label for Linux 2.2.X and upper. */ diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 2564c6f330..8fa91f500c 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3442,6 +3442,9 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, else vty_out(vty, " This interface is UNNUMBERED,"); } else { + struct in_addr dest; + const char *dstr; + /* Show OSPF interface information. */ if (use_json) { json_object_string_add( @@ -3455,46 +3458,40 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf, inet_ntoa(oi->address->u.prefix4), oi->address->prefixlen); - if (oi->connected->destination - || oi->type == OSPF_IFTYPE_VIRTUALLINK) { - struct in_addr *dest; - const char *dstr; + /* For Vlinks, showing the peer address is + * probably more informative than the local + * interface that is being used */ + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) { + dstr = "Peer"; + dest = oi->vl_data->peer_addr; + } else if (CONNECTED_PEER(oi->connected) + && oi->connected->destination) { + dstr = "Peer"; + dest = oi->connected->destination->u.prefix4; + } else { + dstr = "Broadcast"; + dest.s_addr = ipv4_broadcast_addr( + oi->connected->address->u.prefix4.s_addr, + oi->connected->address->prefixlen); + } - if (CONNECTED_PEER(oi->connected) - || oi->type == OSPF_IFTYPE_VIRTUALLINK) - dstr = "Peer"; - else - dstr = "Broadcast"; - - /* For Vlinks, showing the peer address is - * probably more - * * * * * informative than the local - * interface that is being used - * * * * */ + if (use_json) { + json_object_string_add( + json_interface_sub, + "ospfIfType", dstr); if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - dest = &oi->vl_data->peer_addr; - else - dest = &oi->connected->destination->u - .prefix4; - - if (use_json) { json_object_string_add( json_interface_sub, - "ospfIfType", dstr); - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - json_object_string_add( - json_interface_sub, - "vlinkPeer", - inet_ntoa(*dest)); - else - json_object_string_add( - json_interface_sub, - "localIfUsed", - inet_ntoa(*dest)); - } else - vty_out(vty, " %s %s,", dstr, - inet_ntoa(*dest)); - } + "vlinkPeer", + inet_ntoa(dest)); + else + json_object_string_add( + json_interface_sub, + "localIfUsed", + inet_ntoa(dest)); + } else + vty_out(vty, " %s %s,", dstr, + inet_ntoa(dest)); } if (use_json) { json_object_string_add(json_interface_sub, "area", diff --git a/zebra/connected.c b/zebra/connected.c index 4101a4bf24..894aecfd3f 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -143,6 +143,12 @@ static int connected_same(struct connected *ifc1, struct connected *ifc2) if (ifc1->ifp != ifc2->ifp) return 0; + if (ifc1->flags != ifc2->flags) + return 0; + + if (ifc1->conf != ifc2->conf) + return 0; + if (ifc1->destination) if (!ifc2->destination) return 0; @@ -154,12 +160,6 @@ static int connected_same(struct connected *ifc1, struct connected *ifc2) if (!prefix_same(ifc1->destination, ifc2->destination)) return 0; - if (ifc1->flags != ifc2->flags) - return 0; - - if (ifc1->conf != ifc2->conf) - return 0; - return 1; } @@ -276,7 +276,7 @@ void connected_up(struct interface *ifp, struct connected *ifc) /* Add connected IPv4 route to the interface. */ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, - uint16_t prefixlen, struct in_addr *broad, + uint16_t prefixlen, struct in_addr *dest, const char *label, uint32_t metric) { struct prefix_ipv4 *p; @@ -302,59 +302,39 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, : prefixlen; ifc->address = (struct prefix *)p; - /* If there is broadcast or peer address. */ - if (broad) { - p = prefix_ipv4_new(); - p->family = AF_INET; - p->prefix = *broad; - p->prefixlen = prefixlen; - ifc->destination = (struct prefix *)p; - + /* If there is a peer address. */ + if (CONNECTED_PEER(ifc)) { /* validate the destination address */ - if (CONNECTED_PEER(ifc)) { - if (IPV4_ADDR_SAME(addr, broad)) + if (dest) { + p = prefix_ipv4_new(); + p->family = AF_INET; + p->prefix = *dest; + p->prefixlen = prefixlen; + ifc->destination = (struct prefix *)p; + + if (IPV4_ADDR_SAME(addr, dest)) flog_warn( EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER, "warning: interface %s has same local and peer " "address %s, routing protocols may malfunction", ifp->name, inet_ntoa(*addr)); } else { - if (broad->s_addr - != ipv4_broadcast_addr(addr->s_addr, prefixlen)) { - char buf[2][INET_ADDRSTRLEN]; - struct in_addr bcalc; - bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr, - prefixlen); - flog_warn( - EC_ZEBRA_BCAST_ADDR_MISMATCH, - "warning: interface %s broadcast addr %s/%d != " - "calculated %s, routing protocols may malfunction", - ifp->name, - inet_ntop(AF_INET, broad, buf[0], - sizeof(buf[0])), - prefixlen, - inet_ntop(AF_INET, &bcalc, buf[1], - sizeof(buf[1]))); - } - } - - } else { - if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) { zlog_debug( "warning: %s called for interface %s " "with peer flag set, but no peer address supplied", __func__, ifp->name); UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER); } - - /* no broadcast or destination address was supplied */ - if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp)) - zlog_debug( - "warning: PtP interface %s with addr %s/%d needs a " - "peer address", - ifp->name, inet_ntoa(*addr), prefixlen); } + /* no destination address was supplied */ + if (!dest && (prefixlen == IPV4_MAX_PREFIXLEN) + && if_is_pointopoint(ifp)) + zlog_debug( + "warning: PtP interface %s with addr %s/%d needs a " + "peer address", + ifp->name, inet_ntoa(*addr), prefixlen); + /* Label of this address. */ if (label) ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label); @@ -464,7 +444,7 @@ static void connected_delete_helper(struct connected *ifc, struct prefix *p) /* Delete connected IPv4 route to the interface. */ void connected_delete_ipv4(struct interface *ifp, int flags, struct in_addr *addr, uint16_t prefixlen, - struct in_addr *broad) + struct in_addr *dest) { struct prefix p, d; struct connected *ifc; @@ -475,10 +455,10 @@ void connected_delete_ipv4(struct interface *ifp, int flags, p.prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN : prefixlen; - if (broad) { + if (dest) { memset(&d, 0, sizeof(struct prefix)); d.family = AF_INET; - d.u.prefix4 = *broad; + d.u.prefix4 = *dest; d.prefixlen = prefixlen; ifc = connected_check_ptp(ifp, &p, &d); } else @@ -489,7 +469,7 @@ void connected_delete_ipv4(struct interface *ifp, int flags, /* Add connected IPv6 route to the interface. */ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr, - struct in6_addr *broad, uint16_t prefixlen, + struct in6_addr *dest, uint16_t prefixlen, const char *label, uint32_t metric) { struct prefix_ipv6 *p; @@ -514,10 +494,10 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr, p->prefixlen = prefixlen; ifc->address = (struct prefix *)p; - if (broad) { + if (dest) { p = prefix_ipv6_new(); p->family = AF_INET6; - IPV6_ADDR_COPY(&p->prefix, broad); + IPV6_ADDR_COPY(&p->prefix, dest); p->prefixlen = prefixlen; ifc->destination = (struct prefix *)p; } else { @@ -547,7 +527,7 @@ void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr, } void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, - struct in6_addr *broad, uint16_t prefixlen) + struct in6_addr *dest, uint16_t prefixlen) { struct prefix p, d; struct connected *ifc; @@ -557,10 +537,10 @@ void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, memcpy(&p.u.prefix6, address, sizeof(struct in6_addr)); p.prefixlen = prefixlen; - if (broad) { + if (dest) { memset(&d, 0, sizeof(struct prefix)); d.family = AF_INET6; - IPV6_ADDR_COPY(&d.u.prefix6, broad); + IPV6_ADDR_COPY(&d.u.prefix6, dest); d.prefixlen = prefixlen; ifc = connected_check_ptp(ifp, &p, &d); } else diff --git a/zebra/connected.h b/zebra/connected.h index 7672bec006..14f6cb2db0 100644 --- a/zebra/connected.h +++ b/zebra/connected.h @@ -40,12 +40,12 @@ extern struct connected *connected_check_ptp(struct interface *ifp, extern void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr, uint16_t prefixlen, - struct in_addr *broad, const char *label, + struct in_addr *dest, const char *label, uint32_t metric); extern void connected_delete_ipv4(struct interface *ifp, int flags, struct in_addr *addr, uint16_t prefixlen, - struct in_addr *broad); + struct in_addr *dest); extern void connected_delete_ipv4_unnumbered(struct connected *ifc); @@ -53,12 +53,12 @@ extern void connected_up(struct interface *ifp, struct connected *ifc); extern void connected_down(struct interface *ifp, struct connected *ifc); extern void connected_add_ipv6(struct interface *ifp, int flags, - struct in6_addr *address, struct in6_addr *broad, + struct in6_addr *address, struct in6_addr *dest, uint16_t prefixlen, const char *label, uint32_t metric); extern void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address, - struct in6_addr *broad, uint16_t prefixlen); + struct in6_addr *dest, uint16_t prefixlen); extern int connected_is_unnumbered(struct interface *); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 63e72fed00..1f7a1925bc 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -879,11 +879,13 @@ static int netlink_address_ctx(const struct zebra_dplane_ctx *ctx) p = dplane_ctx_get_intf_dest(ctx); addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &p->u.prefix, bytelen); - } else if (cmd == RTM_NEWADDR && - dplane_ctx_intf_has_dest(ctx)) { - p = dplane_ctx_get_intf_dest(ctx); + } else if (cmd == RTM_NEWADDR) { + struct in_addr broad = { + .s_addr = ipv4_broadcast_addr(p->u.prefix4.s_addr, + p->prefixlen) + }; addattr_l(&req.n, sizeof(req), IFA_BROADCAST, - &p->u.prefix, bytelen); + &broad, bytelen); } } diff --git a/zebra/interface.c b/zebra/interface.c index 732e900bbd..e82d2eeb37 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -1081,12 +1081,10 @@ static void connected_dump_vty(struct vty *vty, struct connected *connected) vty_out(vty, "/%d", p->prefixlen); /* If there is destination address, print it. */ - if (connected->destination) { - vty_out(vty, - (CONNECTED_PEER(connected) ? " peer " : " broadcast ")); + if (CONNECTED_PEER(connected) && connected->destination) { + vty_out(vty, " peer "); prefix_vty_out(vty, connected->destination); - if (CONNECTED_PEER(connected)) - vty_out(vty, "/%d", connected->destination->prefixlen); + vty_out(vty, "/%d", connected->destination->prefixlen); } if (CHECK_FLAG(connected->flags, ZEBRA_IFA_SECONDARY)) @@ -2675,12 +2673,6 @@ static int ip_address_install(struct vty *vty, struct interface *ifp, p = prefix_ipv4_new(); *p = pp; ifc->destination = (struct prefix *)p; - } else if (p->prefixlen <= IPV4_MAX_PREFIXLEN - 2) { - p = prefix_ipv4_new(); - *p = lp; - p->prefix.s_addr = ipv4_broadcast_addr(p->prefix.s_addr, - p->prefixlen); - ifc->destination = (struct prefix *)p; } /* Label. */ diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index f93562b31b..624b6d9dd7 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -139,7 +139,7 @@ struct dplane_intf_info { #define DPLANE_INTF_CONNECTED (1 << 0) /* Connected peer, p2p */ #define DPLANE_INTF_SECONDARY (1 << 1) #define DPLANE_INTF_BROADCAST (1 << 2) -#define DPLANE_INTF_HAS_DEST (1 << 3) +#define DPLANE_INTF_HAS_DEST DPLANE_INTF_CONNECTED #define DPLANE_INTF_HAS_LABEL (1 << 4) /* Interface address/prefix */ @@ -1978,9 +1978,6 @@ static enum zebra_dplane_result intf_addr_update_internal( ctx->u.intf.dest_prefix = *(ifc->destination); ctx->u.intf.flags |= (DPLANE_INTF_CONNECTED | DPLANE_INTF_HAS_DEST); - } else if (ifc->destination) { - ctx->u.intf.dest_prefix = *(ifc->destination); - ctx->u.intf.flags |= DPLANE_INTF_HAS_DEST; } if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))